js Event对象的5种坐标


Posted in Javascript onSeptember 12, 2011

但是你懂的,浏览器实在太不和谐了,兼容性且不说,各种坐标属性看得人头昏眼花,极容易混淆。好吧,我来总结一下:

测试浏览器:IE8, Chrome13, FF8, Safari5, Opera11
先上测试用例(用HTML5的doctype测试,也可看出未来的发展趋势,其他doctype可自行测试):

<!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}
也就是说,一个元素的位置信息都给了,我们要做的就是:

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

Javascript 相关文章推荐
让div层随鼠标移动的实现代码 ie ff
Dec 18 Javascript
jQuery AJAX回调函数this指向问题
Feb 08 Javascript
js 数据类型转换总结笔记
Jan 17 Javascript
jQuery实现鼠标滑过遮罩并高亮显示效果
Jul 16 Javascript
js实现多图左右切换功能
Aug 04 Javascript
深入理解JS DOM事件机制
Aug 06 Javascript
Vue.js 和 MVVM 的注意事项
Nov 07 Javascript
jquery实现页面加载效果
Feb 21 Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
Mar 01 Javascript
ES6模板字符串和标签模板的应用实例分析
Jun 25 Javascript
JS操作字符串转数字的常见方法示例
Oct 29 Javascript
Vue项目打包编译优化方案
Sep 16 Javascript
由JavaScript中call()方法引发的对面向对象继承机制call的思考
Sep 12 #Javascript
腾讯UED 漂亮的提示信息效果代码
Sep 12 #Javascript
jQuery的.live()和.die() 使用介绍
Sep 10 #Javascript
jquery tab插件精简版分享
Sep 10 #Javascript
javascript语言结构小记(一)
Sep 10 #Javascript
JavaScript高级程序设计 客户端存储学习笔记
Sep 10 #Javascript
JavaScript高级程序设计 错误处理与调试学习笔记
Sep 10 #Javascript
You might like
MYSQL 小技巧 -- LAST_INSERT_ID
2009/11/24 PHP
php中使用preg_replace函数匹配图片并加上链接的方法
2013/02/06 PHP
PHP中的Streams详细介绍
2014/11/12 PHP
PHP中使用php5-ffmpeg撷取视频图片实例
2015/01/07 PHP
php使用array_search函数实现数组查找的方法
2015/06/12 PHP
在openSUSE42.1下编译安装PHP7 的方法
2015/12/24 PHP
Yii2创建多界面主题(Theme)的方法
2016/10/08 PHP
PHP实现数据库的增删查改功能及完整代码
2018/04/18 PHP
firefox中JS读取XML文件
2006/12/21 Javascript
关于JS字符串函数String.replace()
2013/04/07 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
Bootstrap项目实战之首页内容介绍(全)
2016/04/25 Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
2016/06/08 Javascript
AngularJS 中的事件详解
2016/07/28 Javascript
判断js的Array和Object的实现方法
2016/08/29 Javascript
AngularJS 中的Promise --- $q服务详解
2016/09/14 Javascript
layer实现弹窗提交信息
2016/12/12 Javascript
Javascript中return的使用与闭包详解
2017/01/11 Javascript
浅谈vue实现数据监听的函数 Object.defineProperty
2017/06/08 Javascript
微信小程序访问豆瓣电影api的实现方法
2019/03/31 Javascript
Cordova(ionic)项目实现双击返回键退出应用
2019/09/17 Javascript
JS实现贪吃蛇游戏
2019/11/15 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
Python检测字符串中是否包含某字符集合中的字符
2015/05/21 Python
Python检测生僻字的实现方法
2016/10/23 Python
Python下实现的RSA加密/解密及签名/验证功能示例
2017/07/17 Python
Django Admin 实现外键过滤的方法
2017/09/29 Python
Python3.6安装及引入Requests库的实现方法
2018/01/24 Python
python微信跳一跳系列之棋子定位颜色识别
2018/02/26 Python
python 逆向爬虫正确调用 JAR 加密逻辑
2021/01/12 Python
具有防紫外线功能的高性能钓鱼服装:Hook&Tackle
2018/08/16 全球购物
开展警示教育活动总结
2015/05/09 职场文书
李强为自己工作观后感
2015/06/11 职场文书
简单实现一个手持弹幕功能+文字抖动特效
2021/03/31 HTML / CSS
详解MindSpore自定义模型损失函数
2021/06/30 Python