前辈的文章:
http://www.cnblogs.com/xesam/archive/2011/12/08/2280509.html
http://segmentfault.com/q/1010000000392716
写的小测试:
1. e.pageX 与 e.clientX 的区别
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <style type="text/css"> *{ margin: 0; padding: 0;} #view{ position: relative; left: 25px; top:25px; width: 400px; height: 100px; border: 100px solid #adff2f; background: #ff8c00;} #view_2{ position: absolute; left: 75px; top:375px; width: 300px; height: 100px; background: #008b8b;} #layer{position:absolute;background-color:white; border:1px solid grey;} </style> </head> <body> <div id="fake" style=" position: absolute; left: 10px; top:10px; width: 3000px; height: 2000px; background: #d3d3d3; padding: 50px;"> <div id="view">view</div> <div id="view_2">view_2</div> <div id="layer"></div> </div> <script type="text/javascript"> function mouseMove(e){ var coords = mouseClient(e), div = document.getElementById("layer"); div.style.left = coords.x+20+"px"; div.style.top = coords.y-40+"px"; div.innerHTML = "x:"+coords.x+"px<br />y:"+coords.y+"px"; document.body.appendChild(div); } function mouseCoords(e){ // pageX if (e.pageX || e.pageY){ return {'x':e.pageX, 'y':e.pageY}; }else{ return { 'x':(e.clientX + document.body.scrollLeft - document.body.clientLeft), 'y':(e.clientY + document.body.scrollTop - document.body.clientTop) }; } } function mouseClient(e){ return { 'x':(e.clientX + document.body.scrollLeft), 'y':(e.clientY + document.body.scrollTop) }; //return {'x':(e.clientX), 'y':(e.clientY)}; // 不计滚动条高度, 相对于浏览器窗口 //return {'x':e.pageX, 'y':e.pageY}; // 相对于文档页面,计算滚动条的高度值 = e.clientX + document.body.scrollLeft } document.onmousemove = mouseMove; </script> </body> </html>
2. e.layerX 与 e.offsetX 的区别
e.layerx -- 相对当前坐标系的border左上角开始的坐标
(>ie8 ie9下有特殊表现:相对当前坐标系的border左上角开始的坐标 + 滚动条滚过的距离)
e.offsetX -- 相对当前坐标系的border左上角开始的坐标
何为当前坐标系??
参考文章:
http://shanmao.me/web/js/pagex-clientx-offsetx-layerx-de-qu-bie
粘帖过来:^_^
在各个浏览器的JS中,有很多个让你十分囧的属性,由于各大厂商对标准的解释和执行不一样,导致十分混乱,也让我们这些前端攻城狮十分无语和纠结>_<
John Resig大神说过,动态元素有3个至关重要的元素,位置,尺寸和可见性.所以,今天,先拿几个页面位置属性开刀.
PageX和clientX ,这个两个比较容易搞混,
PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化
clientX:鼠标在页面上可视区域的位置,从浏览器可视区域左上角开始,即是以浏览器滑动条此刻的滑动到的位置为参考点,随滑动条移动 而变化.
真拗口,直接上图,
两个DIV接触点(黑点位置)
如果将浏览器Y轴方向缩小,出现了滑动条就可以分辨出两者的区别
很明显,红色参考块已经被滑动条截取部分,PageY不变,但是clientY已经变了
可是悲剧的是,PageX只有FF特有,IE这个悲剧没有啊T_T,所以大牛们想出了一个办法
PageY=clientY+scrollTop-clientTop;(只讨论Y轴,X轴同理,下同)
页面上的位置=可视区域位置+页面滚动条切去高度-自身border高度,还是直接上图比较清楚
很明显,模块交界处,scrollTop代表的是被浏览器滑动条滚过的长度,和clientY相加,刚好等于100,最后还要再减去一个clientTop,即是border-top的宽度
Jquery中的PageX的代码如下.十分精炼..
1 2 3 4 5 6 |
// Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && event.clientX != null ) { var doc = document.documentElement, body = document.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); } |
screenX:鼠标在屏幕上的位置,从屏幕左上角开始,这个没有任何争议,不讨论 ^_^
接下来是offsetX和layerX
offsetX:IE特有,鼠标相比较于触发事件的元素的位置,以元素盒子模型的内容区域的左上角为参考点,如果有boder,可能出现负值
IE以内容区域开始,向上进入border将出现负值
layerX:FF特有,鼠标相比较于当前坐标系的位置,即如果触发元素没有设置绝对定位或相对定位,以页面为参考点,如果有,将改变参考坐标系,从触发元素盒子模型的border区域的左上角为参考点
也就是当触发元素设置了相对或者绝对定位后,layerX和offsetX就幸福地生活在一起^-^,几乎相等,唯一不同就是一个从border为参考点,一个以内容为参考点
FF从border开始,
x/y:IE特有,这个本来和layerX/layerY的作用基本一样,但是IE的当前坐标选择十分混乱,能不用就不用,不讨论
网上别人总结的关于这六个纠结的纠结表..
1 2 3 4 5 6 |
offsetX/offsetY:W3C- IE+ Firefox- Opera+ Safari+ chrome+ x/y:W3C- IE+ Firefox- Opera+ Safari+ chrome+ layerX/layerY:W3C- IE- Firefox+ Opera- Safari+ chrome+ pageX/pageY:W3C- IE- Firefox+ Opera+ Safari+ chrome+ clientX/clientY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+ screenX/screenY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+ |
只有clientX和screenX 皆大欢喜是W3C标准.其他的,都纠结了.
最给力的是,chrome和safari一条龙通杀!完全支持所有属性.其中(offsetX和layerX都是以border为参考点)…