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 相关文章推荐
javascript Excel操作知识点
Apr 24 Javascript
jquery插件制作 提示框插件实现代码
Aug 17 Javascript
Node.js插件的正确编写方式
Aug 03 Javascript
JS遍历数组及打印数组实例分析
Jan 21 Javascript
Javascript点击按钮随机改变数字与其颜色
Sep 01 Javascript
jQuery异步提交表单的两种方式
Sep 13 Javascript
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
Mar 06 Javascript
vue基于两个计算属性实现选中和全选功能示例
Feb 08 Javascript
vue中的inject学习教程
Apr 24 Javascript
Element-UI中关于table表格的那些骚操作(小结)
Aug 15 Javascript
React Native登录之指纹登录篇的示例代码
Nov 03 Javascript
JS ES6异步解决方案
Apr 29 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输出缓存(output_buffering)的深入理解
2013/06/13 PHP
PHP使用Pthread实现的多线程操作实例
2015/11/14 PHP
Laravel5.1框架注册中间件的三种场景详解
2019/07/09 PHP
jQuery live( type, fn ) 委派事件实现
2009/10/11 Javascript
纯js分页代码(简洁实用)
2013/11/05 Javascript
Javascript类型系统之undefined和null浅析
2016/07/13 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
基于jquery实现二级联动效果
2017/03/30 jQuery
Bootstrap里的文件分别代表什么意思及其引用方法
2017/05/01 Javascript
vue 利用路由守卫判断是否登录的方法
2018/09/29 Javascript
详解js根据百度地图提供经纬度计算两点距离
2019/05/13 Javascript
利用原生JS实现data方法示例代码
2019/05/28 Javascript
JavaScript实现简单计算器
2020/03/19 Javascript
微信小程序连续签到7天积分获得功能的示例代码
2020/08/20 Javascript
基于vue中的scoped坑点解说
2020/09/04 Javascript
js动态添加带圆圈序号列表的实例代码
2021/02/18 Javascript
Python列表append和+的区别浅析
2015/02/02 Python
python中字符串前面加r的作用
2015/06/04 Python
Python中文件的写入读取以及附加文字方法
2019/01/23 Python
Python简易版停车管理系统
2019/08/12 Python
python pymysql库的常用操作
2020/10/16 Python
Python绘图实现台风路径可视化代码实例
2020/10/23 Python
移动端Web页面的CSS3 flex布局快速上手指南
2016/05/31 HTML / CSS
经典C++面试题一
2016/11/06 面试题
电脑租赁公司创业计划书
2014/01/08 职场文书
微笑服务演讲稿
2014/05/13 职场文书
交通安全标语
2014/06/06 职场文书
党的生日活动方案
2014/08/15 职场文书
涉及车辆房产分割的离婚协议书范文
2014/10/12 职场文书
机关干部作风建设剖析材料
2014/10/23 职场文书
小学生毕业评语
2014/12/26 职场文书
店长岗位职责
2015/02/11 职场文书
现场施工员岗位职责
2015/04/11 职场文书
关于远足的感想
2015/08/10 职场文书
参观监狱警示教育心得体会
2016/01/15 职场文书
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android