Event对象的5种坐标
使用鼠标事件经常碰到这样的需求,比如获取鼠标相对于事件源的位置,鼠标相对于事件源对象父元素的位置。。。但是你懂的,浏览器实在太不和谐了,兼容性且不说,各种坐标属性看得人头昏眼花,极容易混淆。好吧,我来总结一下:
测试浏览器:IE8, Chrome13, FF8, Safari5, Opera11
先上测试用例(用HTML5的doctype测试,也可看出未来的发展趋势,其他doctype可自行测试):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <!DOCTYPE html> <html> <head> <meta http-equiv= "Content-Type" content= "text/html;charset=UTF-8" /> <style type= "text/css" > html { background:red; } body { background:green; } #null { height:1000px; } #btn { cursor: default ; background:blue; width:50px; height:30px; line-height:30px; text-align:center; } </style> </head> <body> <div id= 'null' >空白区</div> <div id= "btn" >点击</div><!-- 按钮用DIV是因为原生按钮有圆角,不确定边界 --> </body> <script type= "text/javascript" > window.onload = function (){ var btn = document.getElementById( 'btn' ); btn.onclick = function (e){ e = e|| window.event; var box = (e.target || e.srcElement).getBoundingClientRect(), offsetX = e.clientX - box.left, offsetY = e.clientY - box.top; p( 'x: ' + e.x+ ', y: ' +e.y); p( 'pageX: ' + e.pageX+ ', pageY: ' +e.pageY); p( 'offsetX: ' + e.offsetX+ ', offsetY: ' +e.offsetY); p( 'FF实现 offsetX: ' +offsetX+ ', offsetY: ' +offsetY); p( 'layerX: ' + e.layerX+ ', layerY: ' +e.layerY); p( 'clientX: ' + e.clientX+ ', clientY: ' +e.clientY); p( 'body.scrollLeft: ' + document.body.scrollLeft+ ', body.scrollTop: ' +document.body.scrollTop); p( 'body.clientLeft: ' + document.body.clientLeft + ', body.clientTop: ' +document.body.clientTop); p( 'documentElement.scrollLeft: ' + document.documentElement.scrollLeft+ ', documentElement.scrollTop: ' +document.documentElement.scrollTop); p( 'documentElement.clientLeft: ' + document.documentElement.clientLeft + ', documentElement.clientTop: ' +document.documentElement.clientTop); } } function p(s){ console.log(s); } </script> </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()方法
返回值为:{top:xx, right:xx, bottom:xx, left:xx, width:xx, height:xx}
也就是说,一个元素的位置信息都给了,我们要做的就是:
1 2 3 | var box = (e.target || e.srcElement).getBoundingClientRect(), offsetX = e.clientX - box.left, 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构