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 相关文章推荐
在视频前插入广告
Nov 20 Javascript
网页中CDATA标记的说明
Sep 12 Javascript
JS实现仿中关村论坛评分后弹出提示效果的方法
Feb 23 Javascript
JavaScript引用类型和基本类型详解
Jan 06 Javascript
jquery把int类型转换成字符串类型的方法
Oct 07 Javascript
微信小程序实现图片懒加载的示例代码
Dec 13 Javascript
js构造函数创建对象是否加new问题
Jan 22 Javascript
LayUI表格批量删除方法
Aug 15 Javascript
浅谈Vue数据响应思路之数组
Nov 06 Javascript
JS选取DOM元素常见操作方法实例分析
Dec 10 Javascript
浅谈JavaScript闭包
Apr 09 Javascript
详解Vue中使用插槽(slot)、聚类插槽
Apr 12 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中删除变量时unset()和null的区别分析
2011/01/27 PHP
PHP输出缓冲控制Output Control系列函数详解
2015/07/02 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
2018/06/16 PHP
js 回车提交表单两种实现方法
2012/12/31 Javascript
jquery入门—编写一个导航条(可伸缩)
2013/01/07 Javascript
js自定义事件及事件交互原理概述(一)
2013/02/01 Javascript
js 跳出页面的frameset框架示例介绍
2013/12/23 Javascript
使用原生JS实现弹出层特效
2014/12/22 Javascript
angularJS结合canvas画图例子
2015/02/09 Javascript
javascript中var的重要性分析
2015/02/11 Javascript
JavaScript实现点击文字切换登录窗口的方法
2015/05/11 Javascript
jQuery实现进度条效果代码
2015/12/17 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
js实现日历的简单算法
2017/01/24 Javascript
JS动态添加的div点击跳转到另一页面实现代码
2017/09/30 Javascript
vue 下列表侧滑操作实例代码详解
2018/07/24 Javascript
vue-cli 引入jQuery,Bootstrap,popper的方法
2018/09/03 jQuery
页面内锚点定位及跳转方法总结(推荐)
2019/04/24 Javascript
解析原来浏览器原生支持JS Base64编码解码
2019/08/12 Javascript
Quasar Input:type=&quot;number&quot; 去掉上下小箭头 实现加减按钮样式功能
2020/04/09 Javascript
[01:45]DOTA2众星出演!DSPL刀塔次级职业联赛宣传片
2014/11/21 DOTA
解析Python中的二进制位运算符
2015/05/13 Python
利用标准库fractions模块让Python支持分数类型的方法详解
2017/08/11 Python
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
python用插值法绘制平滑曲线
2021/02/19 Python
python实现弹跳小球
2019/05/13 Python
浅谈PySpark SQL 相关知识介绍
2019/06/14 Python
python selenium登录豆瓣网过程解析
2019/08/10 Python
python解释器spython使用及原理解析
2019/08/24 Python
简单了解django处理跨域请求最佳解决方案
2020/03/25 Python
Python sqlalchemy时间戳及密码管理实现代码详解
2020/08/01 Python
美团网旗下网上订餐平台:美团外卖
2020/03/05 全球购物
医学毕业生自荐信
2013/10/11 职场文书
大学生职业规划范文:象牙塔生活的四年计划
2014/01/14 职场文书
市政工程技术专业自荐书
2014/07/06 职场文书
师德师风个人整改措施
2014/10/27 职场文书