用 Javascript 实现只能输入数字的文本框

在制作表单(Form)的时候,我们通常会给表单元素添加一些输入规则,比如邮件地址、数字等,我们会在特定的时候执行验证,如果验证不通过,会给出一定的提示信息,本文介绍的是用 Javascript 实现只能输入数字的文本框:

用 Javascript 实现只能输入数字的文本框 – 示例

执行验证可以有以下几种方式:
1. 在输入的时候验证,这种验证有一定的特殊性,比如只能输入数字或者只能输入英文字符这样的规则才能应用,如果是 email 验证就不行。

2. 在输入完成时验证,即在 onblur 事件发生时验证。这个适用范围很广,基本上验证都可以使用。

3. 在提交表单时执行验证,即表单的 onsubmit 事件中执行验证。可以一次验证所有元素,适用范围最广。

三种方式第一种实时性最高,输入的时候就验证,第二种次之,在输入完成后验证,第三中最慢,必须在提交时验证,不过每种都有自己的好处和局限性,在应用中可以根据实际情况选用。

本文验证方式是只能输入数字,带有一定的特殊性,可以选用第一种:

 
<script type="text/javascript">
 
// 说明 : 用 Javascript 实现只能输入数字的文本框
// 整理 : CodeBit.cn ( http://www.CodeBit.cn )
 
function checkNumber(e)
{
	var key = window.event ? e.keyCode : e.which;
	var keychar = String.fromCharCode(key);
	var el = document.getElementById('test');
	var msg = document.getElementById('msg');
	reg = /d/;
	var result = reg.test(keychar);
	if(!result) 
	{
		el.className = "warn";
		msg.innerHTML = "只能输入数字";
		return false;
	}
	else
	{
		el.className = "";
		msg.innerHTML = "";
		return true;
	}
}
 
</script>
 
<div id="test">
	请输入数字:<input type="text" onkeypress="return checkNumber(event);" />
	<span id="msg"></span>
</div>

当我们在此元素中输入时,检测用户按键,如果不是数字键,就显示提示信息,实时性较强,当然,我们也可以采用另外两种方式。

用 Javascript 获取滚动条位置等信息

有时为了准确定位一个元素,我们需要获取滚动条的位置,这种需求经常出现在 tooltip 和 拖放等应用中,其实这个技术很简单,关键是要考虑浏览器的兼容性,本文就是介绍这一问题的解决方法。

其实这段代码在之前的 “ 用 Javascript 实现锚点(Anchor)间平滑跳转” 一文已经介绍过了,但是由于这个需求并且经常用到,因此,本站专门发布此文介绍,方便查阅。

 
<script type="text/javascript">
 
// 说明:用 Javascript 获取滚动条位置等信息
// 来源 :ThickBox 2.1 
// 整理 :CodeBit.cn ( http://www.CodeBit.cn )
 
function getScroll() 
{
	var t, l, w, h;
	
	if (document.documentElement && document.documentElement.scrollTop) {
		t = document.documentElement.scrollTop;
		l = document.documentElement.scrollLeft;
		w = document.documentElement.scrollWidth;
		h = document.documentElement.scrollHeight;
	} else if (document.body) {
		t = document.body.scrollTop;
		l = document.body.scrollLeft;
		w = document.body.scrollWidth;
		h = document.body.scrollHeight;
	}
	return { t: t, l: l, w: w, h: h };
}
 
</script>

具体示例请参考 “ 用 Javascript 实现锚点(Anchor)间平滑跳转” 一文。

准确获取指定元素 CSS 属性值

当处理 DOM 元素的 CSS 属性时,我们经常会遇到一个问题:明明页面上已经定义了 CSS 属性值,但在获取的时候却为空,这是因为任何样式表文件或内联 CSS 预设的样式信息并不能可靠地反映到 style 属性上,本文向你介绍准确获取指定元素 CSS 属性值的方法。

准确获取指定元素 CSS 属性值 – 示例

 
<script type="text/javascript">
 
// 说明:准确获取指定元素 CSS 属性值
// 作者:John Resig 《Pro JavaScript Techniques》
// 来源:http://bbs.blueidea.com/viewthread.php?tid=2745446
// 整理:CodeBit.cn ( http://www.CodeBit.cn )
 
function getStyle( elem, name )
{
	//如果该属性存在于style[]中,则它最近被设置过(且就是当前的)
	if (elem.style[name])
	{
		return elem.style[name];
	}
 
	//否则,尝试IE的方式
	else if (elem.currentStyle)
	{
		return elem.currentStyle[name];
	}
 
	//或者W3C的方法,如果存在的话
	else if (document.defaultView && document.defaultView.getComputedStyle)
	{
		//它使用传统的"text-Align"风格的规则书写方式,而不是"textAlign"
		name = name.replace(/([A-Z])/g,"-$1");
		name = name.toLowerCase();
 
		//获取style对象并取得属性的值(如果存在的话)
		var s = document.defaultView.getComputedStyle(elem,"");
		return s && s.getPropertyValue(name);
 
	//否则,就是在使用其它的浏览器
	}
	else
	{
		return null;
	}
}
 
</script>

本文摘录自 John Resig 的《Pro Javascript Techniques》
蓝色 mozart0 版主发布了中文翻译:
http://bbs.blueidea.com/viewthread.php?tid=2733371

用 Javascript 和 CSS 实现脚注(Footnote)效果

脚注(Footnote)是向用户提供更多信息的一个最佳途径,也是主体信息的一个有效补充,常见于各种印刷书籍中。不过,既然脚注有这些好处,我们当然要在网页中也加以利用,本文向您介绍了用 Javascript 和 CSS 实现脚注效果的方法。

用 Javascript 和 CSS 实现脚注(Footnote)效果 – 示例

 
<script type="text/javascript">
 
// 说明:用 Javascript 和 CSS 实现脚注(Footnote)效果
// 作者:CodeBit.cn ( http://www.CodeBit.cn )
 
var footNotes = function(){};
 
footNotes.prototype = {
 
	footNoteClassName : "footnote",	// 脚注的 className
	footNoteTagName : "span",	// 脚注的标签名
	footNoteBackLink : " [back]",	// 返回链接
 
	format : function(contentID, footnoteID)
	{
		if (!document.getElementById) return false;
 
		var content = document.getElementById(contentID);
		var footnote = document.getElementById(footnoteID);
 
		var spans = content.getElementsByTagName(this.footNoteTagName);
 
		var noteArr = [];
		var note = 0;
		
		var elContent;
 
		var len = spans.length;
		for (i=0; i<len; i++)
		{
			note ++;
 
			if (spans[i].className == this.footNoteClassName)
			{
				// 获取脚注内容
				elContent = spans[i].innerHTML;
 
				noteArr.push(elContent);
 
				// 创建一个指向脚注的链接
				var newEle = document.createElement( "a" );
				newEle.href = '#ftn_' + footnoteID + '_' + note;
				newEle.title = "show footnote";
				newEle.id = 'ftnlink_'+footnoteID+'_' + note;
				
				newEle.innerHTML = note;
				
				// 清空原有内容
				while (spans[i].childNodes.length)
				{
					spans[i].removeChild( spans[i].firstChild );
				}
				
				spans[i].appendChild( newEle );
			}
		}
 
		// 创建注释列表
		var ul = this.__buildNoteList(noteArr, footnoteID);
 
		footnote.appendChild(ul);
 
	},
 
	__buildNoteList : function(notes, noteID) 
	{
		if(!notes || notes.length < 1) return;
		
		var ul = document.createElement('ul');
 
		ul.className = this.footNoteClassName;
 
		var li;
 
		var len = notes.length + 1;
		for(i=1; i<len; i++)
		{
			li = document.createElement('li');
			li.id = "ftn_"+noteID+"_"+i;
 
			li.innerHTML = notes[i-1];
 
			// 创建【返回】链接
			var link = document.createElement("a");
			link.href = "#ftnlink_" + noteID + "_" + i;
 
			link.innerHTML = this.footNoteBackLink;
 
			li.appendChild( link );
 
			ul.appendChild( li );
		}
 
		return ul;
	}
};
 
</script>

要实现脚注,我们需要下列元素:

 
<div id="article1">
 
CSS <span class="footnote">CSS 是 Cascading Style Sheet 的缩写。译作「层叠样式表单」。是用于(增强)控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。</span>
 
</div>
	
<div id="artnotes1" class="footnoteHolder"></div>

其中:
article1 是你需要脚注的文章主体
<span class="footnote"> .. </span> 是注释内容,标签 span 和 class 均可配置。
artnotes1 是显示脚注的地方

按照默认的设置调用方式:

 
<script type="text/javascript">
 
	var footnote = new footNotes();
	footnote.format('article1','artnotes1');
 
</script>

如果你想自定义一些内容,可以用下面的方式:

 
<script type="text/javascript">
 
	var footnote = new footNotes();
	footnote.footNoteClassName = "footnote2";
	footnote.footNoteTagName = "em";
	footnote.footNoteBackLink = " [back &laquo;]";
	footnote.format('article1','artnotes1');
 
</script>

在 XHTML-Strict 模式下实现新窗口打开外部链接

熟悉 WEB 标准的朋友都知道,在 XHTML-Strict 模式下,不能给链接设置 target 属性,但是,通常我们都希望外部链接(非本站链接)能够在新窗口打开,如何解决这个冲突呢?本文给出了一个解决方法,希望对您有用!

在 XHTML-Strict 模式下实现新窗口打开外部链接 – 示例

本文的解决方法是在页面加载完成后先用 document.getElementsByTagName(‘a’) 获取页面上所有链接,然后通过搜索链接中是否包含站点 URL ,如果不包含,就说明是外部链接,这时,我们可以通过设置 setAttribute(‘target’, ‘_blank’); 来达到在新窗口打开的目的。

 
<script type="text/javascript">
<!--
 
// 说明:在 XHTML-Strict 模式下实现新窗口打开外部链接
// 作者:CodeBit.cn
// 链接:http://www.codebit.cn
 
function setExternalLinkTarget()
{
	// 从当前 url 中解析主机名
	var locationMatch = document.location.href.match(/^(http://)?([^/]+)/i);
 
	// 设置站点链接
	var siteUrl = locationMatch[2];
 
	// 获取页面上所有链接
	var allLinks = document.getElementsByTagName('a');
	var len = allLinks.length;
 
	if(len > 0)
	{
		var externalLink;
		for(i=0; i<len; i++)
		{
			// 设置当前链接
			externalLink = allLinks[i];
 
			// 如果链接 href 里面没有发现站点链接(外部链接)
			if (externalLink.href.indexOf(siteUrl) == -1)
			{
				// 设置 target 属性
				externalLink.setAttribute('target', '_blank');
			}
		}
	}
}
 
window.onload = function() {
	setExternalLinkTarget();
}
//-->
</script>

日历控件推介之:Dynarch.com Calendar

日历是 WEB 开发中经常用到的控件之一,在和日期相关的表单里,我们通常需要提供一个日期选择器,方便用户使用、提高用户体验。本文向您推介的是 Dynarch.com 开发的一个日历控件,她功能十分健全,内置多种皮肤,支持多种语言,同时提供了一个配置程序,使用非常方便。本文发布时版本为 1.0。

日历控件推介之:Dynarch.com Calendar – 示例

第一步:包含相关文件

 
<!-- 日历控件样式,内置了十种样式 -->
<link rel="stylesheet" type="text/css" media="all" href="calendar-win2k-cold-1.css" title="win2k-cold-1" />
 
<!-- 日历控件主程序 -->
<script type="text/javascript" src="calendar.js"></script>
 
<!-- 日历控件的语言包 -->
<script type="text/javascript" src="lang/calendar-en.js"></script>
 
<!-- 内置的日历控件配置程序,可以让你用几行代码实现控件功能 -->
<script type="text/javascript" src="calendar-setup.js"></script>

第二步:根据你的表单元素设置日历控件

 
<form action="#" method="get">
<input type="text" name="date" id="f_date_b" /><button type="reset" id="f_trigger_b">...</button>
</form>
 
<script type="text/javascript">
	Calendar.setup({
		inputField     :    "f_date_b",      // id of the input field
		ifFormat       :    "%m/%d/%Y %I:%M %p",       // format of the input field
		showsTime      :    true,            // will display a time selector
		button         :    "f_trigger_b",   // trigger for the calendar (button ID)
		singleClick    :    false,           // double-click mode
		step           :    1                // show all years in drop-down boxes (instead of every other year as default)
	});
</script>

内置的配置程序里面提供了丰富的配置参数,能让你实现大多数日历控件功能,具体说明请参考说明文档。

源代码下载地址:
http://prdownloads.sourceforge.net/jscalendar/jscalendar-1.0.zip?download

在线文档:(英文)
http://www.dynarch.com/demos/jscalendar/doc/html/reference.html

Javascript 实现无刷新联动菜单(select)的方法

所谓联动菜单,就是后一个下拉框的选项是根据前一个下拉框被选中的值来决定的,一个典型的应用就是省市联动菜单了,市的下拉选项是根据你选了哪个省来决定的,类似的需求我们经常遇到,相信许多新手都被这个问题困扰过。

其实,联动菜单的实现原理非常简单,本文详细介绍了联动菜单的实现方式,知道了原理,我们可以很容易地制作从XML、数据库加载的无限级联动菜单。

Javascript 实现无刷新联动菜单(select)的方法 – 示例

联动菜单的实现方法:

1.确定数据格式:

首先,我们介绍一下创建 Option 的语法:

 
var newOption = new Option(optionText, optionvalue);

根据上面的语法,我们知道 select 选项分 optionText 和 optionvalue 两个内容,optionText 即下拉框中我们看到的选项,而 optionvalue 则是提交的实际值。比如一个选项我们看到的是 “北京”,而实际提交的值是 “010”。

为了保持一致,我们确定选项的格式为:

 
{txt:"选项名", val:"选项值"}

那么一个选项组则是:

 
var childArr = [];
 
childArr['父选项值1'] = [
	{txt:"选项名1", val:"选项值1"}, 
	{txt:"选项名2", val:"选项值2"},
	{txt:"选项名3", val:"选项值3"},
	...
	{txt:"选项名n", val:"选项值n"}
]
 
childArr['父选项值2'] = [
	{txt:"选项名1", val:"选项值1"}, 
	{txt:"选项名2", val:"选项值2"},
	{txt:"选项名3", val:"选项值3"},
	...
	{txt:"选项名n", val:"选项值n"}
]

其中“父选项值”是父下拉列表选中的值。

注意:[ ] 和 {} 中的值是以“,” (逗号)分隔的,但是最后一个值后面不能有 “,” (逗号),否则语法错误, PHP 程序员要特别注意 !!!

2.根据传入的数组创建选项列表:

 
for (var i=0; i < len; i++)
{
	selectObj.options[i] = new Option(optionList[i].txt, optionList[i].val);
}

3.在设置选项之前,我们需要先将原有选项清空:

 
function removeOptions(selectObj)
{
	if (typeof selectObj != 'object')
	{
		selectObj = document.getElementById(selectObj);
	}
 
	// 原有选项计数
	var len = selectObj.options.length;
 
	for (var i=0; i < len; i++)
	{
		// 移除当前选项
		selectObj.options[0] = null;
	}
}

注意,这里不是用 selectObj.options[i] 而是用的 selectObj.options[0] ,由于在 options[0] 删除后,后面的选项就会补上,因此,我们只需要 selectObj.options[0] = null 。

4.设置一个提示选择项和默认选择项:

通常我们在下拉列表中会设置一个提示选择项,如:“请选择城市”,这个选项值为空,作用只是提示用户执行选择操作。

另外,下拉列表也需要能够设置默认选择项,即在页面加载的时候,设置选中状态的项目。

完整代码如下:

 
<script language="JavaScript" type="text/javascript">
<!--
 
/*
 * 说明:将指定下拉列表的选项值清空
 * 作者:CodeBit.cn ( http://www.CodeBit.cn )
 *
 * @param {String || Object]} selectObj 目标下拉选框的名称或对象,必须
 */
function removeOptions(selectObj)
{
	if (typeof selectObj != 'object')
	{
		selectObj = document.getElementById(selectObj);
	}
 
	// 原有选项计数
	var len = selectObj.options.length;
 
	for (var i=0; i < len; i++)
	{
		// 移除当前选项
		selectObj.options[0] = null;
	}
}
 
/*
 * 说明:设置传入的选项值到指定的下拉列表中
 * 作者:CodeBit.cn ( http://www.CodeBit.cn )
 *
 * @param {String || Object]} selectObj 目标下拉选框的名称或对象,必须
 * @param {Array} optionList 选项值设置 格式:[{txt:'北京', val:'010'}, {txt:'上海', val:'020'}] ,必须
 * @param {String} firstOption 第一个选项值,如:“请选择”,可选,值为空
 * @param {String} selected 默认选中值,可选
 */
function setSelectOption(selectObj, optionList, firstOption, selected)
{
	if (typeof selectObj != 'object')
	{
		selectObj = document.getElementById(selectObj);
	}
 
	// 清空选项
	removeOptions(selectObj);
 
	// 选项计数
	var start = 0;
	
	// 如果需要添加第一个选项
	if (firstOption)
	{
		selectObj.options[0] = new Option(firstOption, '');
 
		// 选项计数从 1 开始
		start ++;
	}
 
	var len = optionList.length;
 
	for (var i=0; i < len; i++)
	{
		// 设置 option
		selectObj.options[start] = new Option(optionList[i].txt, optionList[i].val);
 
		// 选中项
		if(selected == optionList[i].val)
		{
			selectObj.options[start].selected = true;
		}
 
		// 计数加 1
		start ++;
	}
 
}
 
//-->
</script>

示例代码:

 
<script language="JavaScript" type="text/javascript">
 
var cityArr = [];
cityArr['江苏省'] = [
		{txt:'南京', val:'南京'}, 
		{txt:'无锡', val:'无锡'},
		{txt:'徐州', val:'徐州'},
		{txt:'苏州', val:'苏州'},
		{txt:'南通', val:'南通'},
		{txt:'淮阴', val:'淮阴'},
		{txt:'扬州', val:'扬州'},
		{txt:'镇江', val:'镇江'},
		{txt:'常州', val:'常州'}
	];
cityArr['浙江省'] = [
		{txt:'杭州', val:'杭州'}, 
		{txt:'宁波', val:'宁波'},
		{txt:'温州', val:'温州'},
		{txt:'湖州', val:'湖州'}
	];
 
function setCity(province)
{	
	setSelectOption('city', cityArr[province], '-请选择-');
}
 
</script>
 
<select name="province" id="province" onchange="if(this.value != '') setCity(this.options[this.selectedIndex].value);">
	<option value="">-请选择-</option>
	<option value="江苏省">江苏省</option>
	<option value="浙江省">浙江省</option>
</select> 省
 
<select name="city" id="city">
	<option value="">-请选择-</option>
</select> 市

根据这个结构,设置好数据,我们可以很容易的实现无限级联动菜单。或者我们也可以将数据存放在文件或数据库中,通过 Ajax 获取数据。

一个非常健全的 Javascript 链接(URL)解析类

用 Javascript 解析链接(URL)是一个常见的需求,本文介绍了一个非常健全的用 Javascript 写的链接(URL)解析类,他可以准确获取一个完整的 URL 中每个部分的内容,包括协议、URL中包含的用户名和密码、主机名、端口、路径名、参数、锚点(Fragment Anchor)等信息。

其实他的方法就是常见的正则匹配,但是整个实现写的很精巧,非常值得 javascript 新手研究。

一个非常健全的 Javascript 链接(URL)解析类 – 示例

 
<script type="text/javascript">
 
// 说明:一个非常健全的 Javascript 链接(URL)解析类
// 整理:http://www.CodeBit.cn
 
/** 
* @projectDescription 	Poly9's polyvalent URLParser class
*
* @author	Denis Laprise - denis@poly9.com - http://poly9.com
* @version	0.1 
* @namespace	Poly9
*
* See the unit test file for more examples.
* URLParser is freely distributable under the terms of an MIT-style license.
*/
 
if (typeof Poly9 == 'undefined')
{
	var Poly9 = {};
}
 
/**
 * Creates an URLParser instance
 *
 * @classDescription	Creates an URLParser instance
 * @return {Object}	return an URLParser object
 * @param {String} url	The url to parse
 * @constructor
 * @exception {String}  Throws an exception if the specified url is invalid
 */
Poly9.URLParser = function(url) {
 
	this._fields = {
		'Username' : 4, 
		'Password' : 5, 
		'Port' : 7, 
		'Protocol' : 2, 
		'Host' : 6, 
		'Pathname' : 8, 
		'URL' : 0, 
		'Querystring' : 9, 
		'Fragment' : 10
	};
 
	this._values = {};
	this._regex = null;
	this.version = 0.1;
	this._regex = /^((w+)://)?((w+):?(w+)?@)?([^/?:]+):?(d+)?(/?[^?#]+)???([^#]+)?#?(w*)/;
 
	for(var f in this._fields)
	{
		this['get' + f] = this._makeGetter(f);
	}
 
	if (typeof url != 'undefined')
	{
		this._parse(url);
	}
}
 
/**
 * @method 
 * @param {String} url	The url to parse
 * @exception {String} 	Throws an exception if the specified url is invalid
 */
Poly9.URLParser.prototype.setURL = function(url) {
	this._parse(url);
}
 
Poly9.URLParser.prototype._initValues = function() {
	for(var f in this._fields)
	{
		this._values[f] = '';
	}
}
 
Poly9.URLParser.prototype._parse = function(url) {
	this._initValues();
	var r = this._regex.exec(url);
	if (!r) throw "DPURLParser::_parse -> Invalid URL";
 
	for(var f in this._fields) if (typeof r[this._fields[f]] != 'undefined')
	{
		this._values[f] = r[this._fields[f]];
	}
}
 
Poly9.URLParser.prototype._makeGetter = function(field) {
	return function() {
		return this._values[field];
	}
}
 
</script>

示例代码:

 
<script type="text/javascript">
 
var url = 'http://user:password@www.codebit.cn:9901/pub/article.php?offset=10&perpage=10#fragment';
 
var p = new Poly9.URLParser(url);
 
document.write("<strong>URL:</strong> " + url + "<br /><br />");
document.write("解析结果如下:<br /><br />");
document.write("<strong>Protocol:</strong> " + p.getProtocol() + "<br />");
document.write("<strong>Username:</strong> " + p.getUsername() + "<br />");
document.write("<strong>Password:</strong> " + p.getPassword() + "<br />");
document.write("<strong>Host:</strong> " + p.getHost() + "<br />");
document.write("<strong>Port:</strong> " + p.getPort() + "<br />");
document.write("<strong>Pathname:</strong> " + p.getPathname() + "<br />");
document.write("<strong>Query String:</strong> " + p.getQuerystring() + "<br />");
document.write("<strong>Fragment:</strong> " + p.getFragment() + "<br />");
 
</script>

用 javascript 获取当页面上鼠标(光标)位置

用 javascript 获取当页面上鼠标(光标)位置在许多情况下都会用到,比如拖放,悬停提示(tooltip) 等等。当然,这里我们依然要面对浏览器的兼容问题,在不同的浏览器下,对这些相关的属性处理方式也不同,本文详细介绍了浏览器在处理这些属性时的差异和最终的解决方法。

用 javascript 获取当页面上鼠标(光标)位置 – 示例

 
<script type="text/javascript">
 
// 说明:获取鼠标位置
// 整理:http://www.codebit.cn
// 来源:http://www.webreference.com
 
function mousePosition(ev){
	if(ev.pageX || ev.pageY){
		return {x:ev.pageX, y:ev.pageY};
	}
	return {
		x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:ev.clientY + document.body.scrollTop  - document.body.clientTop
	};
}
 
</script>

上面的代码我们在 怎么用 javascript 实现拖拽 中已经介绍过了,由于这个需求我们经常用到,所以我们将这段代码独立成一篇文章,供新手查询。

使用方式:

 
 
document.onmousemove = mouseMove;
 
function mouseMove(ev){
	ev = ev || window.event;
	var mousePos = mousePosition(ev);
}

关于代码的详细说明,原文中已经介绍,现转到此处:

我们首先要声明一个 evnet 对象,无论移动、点击、按键等,都会激活一个 evnet ,在 Internet Explorer 里, event 是全局变量,会被存储在 window.event 里. 在 firefox 或者其他浏览器,event 会被相应的函数获取.当我们将mouseMove函数赋值于document.onmousemove,mouseMove 会获取鼠标移动事件。

为了让 ev 在所有浏览器下获取了 event 事件,在Firefox下"||window.event"将不起作用,因为ev已经有了赋值。在 MSIE 中 ev 为空,所以得到 window.event 。

因为在这篇文章中我们需要多次获取鼠标位置,所以我们设计了一个 mousePosition 函数,它包含一个参数 : event 。

因为我们要在 MSIE 和其他浏览器下运行,Firefox 和其他浏览器用 event.pageX 和 event.pageY 来表示鼠标相对于文档的位置,如果你有一个 500*500 的窗口并且你的鼠标在绝对中间,那么 pageX 和 pageY 的值都是 250,如果你向下滚动 500, 那么 pageY 将变成 750。

MSIE 正好相反,它使用 event.clientX 和 event.clientY 表示鼠标相当于窗口的位置,而不是文档。在同样的例子中,如果你向下滚动500,clientY 依然是 250,因此,我们需要添加 scrollLeft 和 scrollTop 这两个相对于文档的属性。最后,MSIE 中文档并不是从 0,0 开始,而是通常有一个小的边框(通常是 2 象素),边框的大小定义在 document.body.clientLeft 和 clientTop 中,我们也把这些加进去。

很幸运,我们现在已经用 mousePosition 函数解决了坐标问题,不需为此费心了。

用 Javascript 获取指定页面元素的位置

用 Javascript 获取指定页面元素的位置是一个非常常见的需求,本文介绍的方法能够准确返回一个元素相对于整个文档左上角的坐标,即元素的 top 、left 的位置,而且能够兼容浏览器,相信对新手非常有用。

用 Javascript 获取指定页面元素的位置 – 示例

 
<script language="JavaScript" type="text/javascript">
<!--
 
// 说明:用 Javascript 获取指定页面元素的位置
// 整理:http://www.codebit.cn
// 来源:YUI DOM
 
function getElementPos(elementId) {
 
	var ua = navigator.userAgent.toLowerCase();
	var isOpera = (ua.indexOf('opera') != -1);
	var isIE = (ua.indexOf('msie') != -1 && !isOpera); // not opera spoof
 
	var el = document.getElementById(elementId);
 
	if(el.parentNode === null || el.style.display == 'none') 
	{
		return false;
	}
 
	var parent = null;
	var pos = [];
	var box;
 
	if(el.getBoundingClientRect)	//IE
	{
		box = el.getBoundingClientRect();
		var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
		var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
 
		return {x:box.left + scrollLeft, y:box.top + scrollTop};
	}
	else if(document.getBoxObjectFor)	// gecko
	{
		box = document.getBoxObjectFor(el);
		   
		var borderLeft = (el.style.borderLeftWidth)?parseInt(el.style.borderLeftWidth):0;
		var borderTop = (el.style.borderTopWidth)?parseInt(el.style.borderTopWidth):0;
 
		pos = [box.x - borderLeft, box.y - borderTop];
	}
	else	// safari & opera
	{
		pos = [el.offsetLeft, el.offsetTop];
		parent = el.offsetParent;
		if (parent != el) {
			while (parent) {
				pos[0] += parent.offsetLeft;
				pos[1] += parent.offsetTop;
				parent = parent.offsetParent;
			}
		}
		if (ua.indexOf('opera') != -1 
			|| ( ua.indexOf('safari') != -1 && el.style.position == 'absolute' )) 
		{
				pos[0] -= document.body.offsetLeft;
				pos[1] -= document.body.offsetTop;
		} 
	}
		
	if (el.parentNode) { parent = el.parentNode; }
	else { parent = null; }
  
	while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') 
	{ // account for any scrolled ancestors
		pos[0] -= parent.scrollLeft;
		pos[1] -= parent.scrollTop;
  
		if (parent.parentNode) { parent = parent.parentNode; } 
		else { parent = null; }
	}
	return {x:pos[0], y:pos[1]};
}
 
//-->
</script>