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 相关文章推荐
JS 分号引起的一段调试问题
Jun 18 Javascript
JavaScript学习笔记(十)
Jan 17 Javascript
jQuery性能优化28条建议你值得借鉴
Feb 16 Javascript
Javascript实现关联数据(Linked Data)查询及注意细节
Feb 22 Javascript
三种动态加载js的jquery实例代码另附去除js方法
Apr 30 Javascript
node.js中的fs.statSync方法使用说明
Dec 16 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
Jun 18 Javascript
微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义实例
Dec 08 Javascript
Bootstrap基本模板的使用和理解1
Dec 14 Javascript
从0到1构建vueSSR项目之node以及vue-cli3的配置
Mar 07 Javascript
小程序和web画三角形实现解析
Sep 02 Javascript
Vue基于iview实现登录密码的显示与隐藏功能
Mar 06 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
PHP 采集程序 常用函数
2008/12/18 PHP
PHP实现将HTML5中Canvas图像保存到服务器的方法
2014/11/28 PHP
php通过session防url攻击方法
2014/12/10 PHP
jquery中html、val与text三者属性取值的联系与区别介绍
2013/12/29 Javascript
Javascript编程之继承实例汇总
2015/11/28 Javascript
BootStrap扔进Django里的方法详解
2016/05/13 Javascript
微信小程序 五星评价功能的实现
2017/03/09 Javascript
Avalonjs双向数据绑定与监听的实例代码
2017/06/23 Javascript
详解使用Vue Router导航钩子与Vuex来实现后退状态保存
2017/09/11 Javascript
详解Vue2.0配置mint-ui踩过的那些坑
2018/04/23 Javascript
在Vue-cli里应用Vuex的state和mutations方法
2018/09/16 Javascript
基于Nodejs的Tcp封包和解包的理解
2018/09/19 NodeJs
微信小程序模板template简单用法示例
2018/12/04 Javascript
Vue 实现手动刷新组件的方法
2019/02/19 Javascript
更优雅的微信小程序骨架屏实现详解
2019/08/07 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
Vue 解决父组件跳转子路由后当前导航active样式消失问题
2020/07/21 Javascript
python中enumerate的用法实例解析
2014/08/18 Python
python实现unicode转中文及转换默认编码的方法
2017/04/29 Python
使用python判断你是青少年还是老年人
2018/11/29 Python
python石头剪刀布小游戏(三局两胜制)
2021/01/20 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
2019/07/14 Python
Python 画出来六维图
2019/07/26 Python
pytorch中tensor张量数据类型的转化方式
2019/12/31 Python
HTML5 canvas实现雪花飘落特效
2016/03/08 HTML / CSS
英国领先的鞋类零售商和顶级品牌的官方零售商:Wynsors
2020/02/17 全球购物
建筑设计师岗位职责
2013/11/18 职场文书
2014年两会学习心得范例
2014/03/17 职场文书
父母对孩子说的话
2014/04/12 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书
工作表扬信范文
2015/01/17 职场文书
离婚协议书样本
2015/01/26 职场文书
2015年政风行风工作总结
2015/04/21 职场文书
《小摄影师》教学反思
2016/02/18 职场文书
学生会自荐信
2019/05/16 职场文书
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android