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 相关文章推荐
如何取得中文输入的真实长度?
Jun 24 Javascript
jQuery实现表单input中提示文字value随鼠标焦点移进移出而显示或隐藏的代码
Mar 21 Javascript
jQuery调用WebService的实现代码
Jun 19 Javascript
jQuery Ajax使用实例
Apr 16 Javascript
javascript实现倒计时跳转页面
Jan 17 Javascript
省市联动效果的简单实现代码(推荐)
Jun 06 Javascript
Node.js与MySQL交互操作及其注意事项
Oct 05 Javascript
微信小程序 rpx 尺寸单位详细介绍
Oct 13 Javascript
微信小程序 MD5的方法详解及实例代码
Mar 10 Javascript
KnockoutJS数组比较算法实例详解
Nov 25 Javascript
JavaScript简单编程实例学习
Feb 14 Javascript
JS监听Esc 键触发事键
Apr 14 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 iconv 函数转gb2312的bug解决方法
2009/10/11 PHP
简介PHP的Yii框架中缓存的一些高级用法
2016/03/29 PHP
PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题
2016/08/12 PHP
php 生成签名及验证签名详解
2016/10/26 PHP
PHP实现类似题库抽题效果
2018/08/16 PHP
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
2013/04/15 Javascript
Jquery实现显示和隐藏的4种简单方式
2013/08/28 Javascript
javascript获取重复次数最多的字符
2015/07/08 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
javascript基础语法学习笔记
2016/01/04 Javascript
VC调用javascript的几种方法(推荐)
2016/08/09 Javascript
在javascript中使用com组件的简单实现方法
2016/08/17 Javascript
Jquery把获取到的input值转换成json
2017/05/15 jQuery
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
2018/01/07 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
vue2.0结合Element-ui实战案例
2019/03/06 Javascript
使用React手写一个对话框或模态框的方法示例
2019/04/25 Javascript
[02:32]DOTA2亚洲邀请赛 C9战队出场宣传片
2015/02/07 DOTA
python实现socket端口重定向示例
2014/02/10 Python
Python中输出ASCII大文字、艺术字、字符字小技巧
2015/04/28 Python
Python 运行.py文件和交互式运行代码的区别详解
2019/07/02 Python
解决TensorFlow模型恢复报错的问题
2020/02/06 Python
python图片剪裁代码(图片按四个点坐标剪裁)
2020/03/10 Python
python 识别登录验证码图片功能的实现代码(完整代码)
2020/07/03 Python
全球立体声:World Wide Stereo
2018/09/29 全球购物
远东集团网络工程师面试题
2014/10/20 面试题
Exception类的常用方法
2012/06/16 面试题
弄虚作假心得体会
2014/09/10 职场文书
群众路线自查报告及整改措施
2014/11/04 职场文书
2014年个人业务工作总结
2014/11/17 职场文书
会议通知范文
2015/04/15 职场文书
学校节水倡议书
2015/04/29 职场文书
董事会决议范本
2015/07/01 职场文书
公司档案管理制度
2015/08/05 职场文书
导游词之云南丽江古城
2019/09/17 职场文书
解决MySQL存储时间出现不一致的问题
2021/04/28 MySQL