Chinaunix

标题: Event对象的5种坐标 [打印本页]

作者: so_brave    时间: 2011-09-12 21:57
标题: Event对象的5种坐标
Event对象的5种坐标

使用鼠标事件经常碰到这样的需求,比如获取鼠标相对于事件源的位置,鼠标相对于事件源对象父元素的位置。。。但是你懂的,浏览器实在太不和谐了,兼容性且不说,各种坐标属性看得人头昏眼花,极容易混淆。好吧,我来总结一下:





测试浏览器:IE8, Chrome13,  FF8, Safari5, Opera11

先上测试用例(用HTML5的doctype测试,也可看出未来的发展趋势,其他doctype可自行测试):

show sourceview sourceprint?
  1. 01 <!DOCTYPE html>  

  2. 02 <html>  

  3. 03 <head>  

  4. 04     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>  

  5. 05     <style type="text/css">  

  6. 06         html {  

  7. 07             background:red;  

  8. 08         }  

  9. 09         body {  

  10. 10             background:green;  

  11. 11         }

  12. 12         #null {  

  13. 13             height:1000px;  

  14. 14         }

  15. 15         #btn {  

  16. 16             cursor:default;  

  17. 17             background:blue;  

  18. 18             width:50px;  

  19. 19             height:30px;  

  20. 20             line-height:30px;  

  21. 21             text-align:center;  

  22. 22         }  

  23. 23     </style>  

  24. 24 </head>  

  25. 25 <body>  

  26. 26     <div id='null'>空白区</div>  

  27. 27     <div id="btn">点击</div><!-- 按钮用DIV是因为原生按钮有圆角,不确定边界 -->  

  28. 28 </body>  

  29. 29   

  30. 30 <script type="text/javascript">  

  31. 31     window.onload = function(){   

  32. 32         var btn = document.getElementById('btn');  

  33. 33         btn.onclick = function(e){  

  34. 34             e = e|| window.event;  

  35. 35             var box = (e.target || e.srcElement).getBoundingClientRect(),  

  36. 36                 offsetX = e.clientX - box.left,  

  37. 37                 offsetY = e.clientY - box.top;  

  38. 38             p('x: '+ e.x+', y: '+e.y);  

  39. 39             p('pageX: '+ e.pageX+', pageY: '+e.pageY);  

  40. 40             p('offsetX: '+ e.offsetX+', offsetY: '+e.offsetY);  

  41. 41             p('FF实现 offsetX: '+offsetX+', offsetY: '+offsetY);  

  42. 42             p('layerX: '+ e.layerX+', layerY: '+e.layerY);  

  43. 43             p('clientX: '+ e.clientX+', clientY: '+e.clientY);  

  44. 44             p('body.scrollLeft: '+ document.body.scrollLeft+', body.scrollTop: '+document.body.scrollTop);  

  45. 45             p('body.clientLeft: ' + document.body.clientLeft + ', body.clientTop: '+document.body.clientTop);  

  46. 46             p('documentElement.scrollLeft: '+ document.documentElement.scrollLeft+', documentElement.scrollTop: '+document.documentElement.scrollTop);  

  47. 47             p('documentElement.clientLeft: ' + document.documentElement.clientLeft + ', documentElement.clientTop: '+document.documentElement.clientTop);  

  48. 48         }  

  49. 49     }  

  50. 50     function p(s){  

  51. 51         console.log(s);  

  52. 52     }  

  53. 53 </script>  

  54. 54 </html>
复制代码
问:怎样获取鼠标相对于浏览器可视文档区域左上角的位置?

答:x, y和clientX, clientY皆可,但是x, y在IE下表示鼠标相对于文档开头的位置(即如果有滚到条的话,会计算在内),还有FF也不支持x, y

  推荐: clientX, clientY






问:怎样获取鼠标相对于文档开头的位置?

答:   IE:使用x, y(前提是事件源的父元素(一直到documentElement)没有设置position:relative之类的,否则相对于最近元素,而非相对于文档)

  非IE:使用pageX, pageY

  layerX, layerY其实也可以,但是IE和Opera不支持!

  那么如何确保IE正常取值呢?答:event.clientX + document.documentElement.scrollLeft,  event.clientY + document.documentElement.scrollTop






问:怎样获取鼠标相对于事件源(event.target||event.srcElement)左上角的位置?

答:offsetX, offsetY。但是FF不支持,怎样办呢?

  1. 先获取鼠标相对于浏览器可视文档区域左上角的位置

  2. 然后获取事件源相对于浏览器可视文档区域左上角的位置

  3. 相减,收工



也许有人会问,这第2步怎么做啊?好吧,好人做到底!

HTMLElement.getBoundingClientRect()方法

返回值为:{topx, rightx, bottomx, leftx, widthx, heightx}

也就是说,一个元素的位置信息都给了,我们要做的就是:

view sourceprint?1 var box = (e.target || e.srcElement).getBoundingClientRect(),  

2     offsetX = e.clientX - box.left,  

3     offsetY = e.clientY - box.top;

经测试,所有浏览器都和event.offsetX, event.offsetY保持一致(当然FF除外)






我的例子中,最后还检测了scrollLeft, scrollTop, clientLeft, clientTop,本来以为它们几个会作怪,可测试结果表明:

除了scrollTop,其他都是0(当然scrollLeft是因为没出现横向滚动条所致)

scrollTop各浏览器表现不尽相同,如下:

body.scrollTop的情况

  IE, FF, Opera:0

  Chrome, Safari:向上滚动的距离

documentElement.scrollTop的情况

  IE, FF, Opera:向上滚动的距离

  Chrome, Safari:0




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2