首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议125:设计鼠标指针定位方案

关灯直达底部

当事件发生时,获取鼠标指针的位置是很重要的操作。不同浏览器分别在各自事件对象中定义了不同的属性,见表6.1。这些属性都以像素值定义了鼠标指针的坐标,但它们参照的坐标系不同,从而使准确计算鼠标的位置(能够兼容不同浏览器)成为一件很麻烦的事。

首先,screenX和screenY这两个属性获得了所有浏览器的支持,应该说是最优选用属性。它们的坐标系是计算机屏幕,也就是说,以计算机屏幕左上角为定位原点。这对于以浏览器窗口为活动空间的网页来说,没有任何价值,因为不同的屏幕分辨率,不同的浏览器窗口大小和位置都使在网页中定位鼠标成为一件很困难的事情。

如果以document对象为坐标系,则可以考虑选用pageX和pageY属性在浏览器窗口中进行定位。这对设计鼠标跟随来说是一个好主意,因为跟随元素一般都以绝对定位的方式在浏览器窗口中移动,所以只要在mousemove事件处理函数中把pageX和pageY属性值传递给绝对定位元素的top和left样式属性即可。

由于clientX和clientY属性是以window对象为坐标系,并且IE支持它们,因此可以选用它们。不过考虑window等对象可能出现的滚动条偏移量,还应加上相对于window对象的页面滚动的偏移量。因此可以这样来设计:


var posX=0,posY=0;

var event=event||window.event;

if(event.pageX||event.pageY){

posX=event.pageX;

posY=event.pageY;

}

else if(event.clientX||event.clientY){

posX=event.clientX+document.documentElement.scrollLeft+document.body.scrollLeft;

posY=event.clientY+document.documentElement.scrollTop+document.body.scrollTop;

}


在上面的代码中,先检测pageX和pageY属性是否存在,如果存在,则获取它们的值;如果不存在,则检测并获取clientX和clientY属性值,然后加上document.documentElement和document.body对象的scrollLeft和scrollTop属性值,这样就可以在不同浏览器中获得相同的坐标值。

然后定义一个封装函数,设计函数传入参数为对象引用指针、相对鼠标指针的偏移距离,以及事件对象。接着封装函数能够根据事件对象获取鼠标的坐标值,并设置该对象为绝对定位,绝对定位的值为鼠标指针当前的坐标值。具体封装代码如下:


var pos=function(o,x,y,event){

var posX=0,posY=0;

var e=event||window.event;

if(e.pageX||e.pageY){

posX=e.pageX;

posY=e.pageY;

}

else if(e.clientX||e.clientY){

posX=e.clientX+document.documentElement.scrollLeft+document.body.scrollLeft;

posY=e.clientY+document.documentElement.scrollTop+document.body.scrollTop;

}

o.style.position="absolute";

o.style.top=(posY+y)+"px";

o.style.left=(posX+x)+"px";

}


为document对象注册鼠标移动事件处理函数,并传入鼠标定位封装函数,传入的对象为<p>元素,设置其位置向鼠标指针右下方偏移(10,20)的距离。由于非IE浏览器是通过参数形式传递事件对象的,所以不要忘记在调用函数中还要传递事件对象。代码如下:


<p>鼠标跟随</p>

<script language="javascript"type="text/javascript">

var p1=document.getElementById("p1");

document.onmousemove=function(event){

pos(p1,10,20,event);

}

</script>