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 相关文章推荐
zTree插件之单选下拉菜单实例代码
Nov 07 Javascript
jquery ajax,ashx,json的用法总结
Feb 12 Javascript
Jquery焦点与失去焦点示例应用
Jun 10 Javascript
Bootstrap每天必学之进度条
Nov 30 Javascript
JavaScript使用简单正则表达式的数据验证功能示例
Jan 13 Javascript
详解vue2.0组件通信各种情况总结与实例分析
Mar 22 Javascript
JavaScript屏蔽Backspace键的实现代码
Nov 02 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
May 30 Javascript
node和vue实现商城用户地址模块
Dec 05 Javascript
Vue通过Blob对象实现导出Excel功能示例代码
Jul 31 Javascript
原生JS实现九宫格抽奖
Sep 13 Javascript
Node.js利用Express实现用户注册登陆功能(推荐)
Oct 26 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访问查询mysql数据的三种方法
2006/10/09 PHP
php分页代码学习示例分享
2014/02/20 PHP
php三元运算符知识汇总
2015/07/02 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
基于Flowplayer打造一款免费的WEB视频播放器附源码
2015/09/06 Javascript
javascript实现Email邮件显示与删除功能
2015/11/21 Javascript
jquery读写cookie操作实例分析
2015/12/24 Javascript
基于JS实现Android,iOS一个手势动画效果
2016/04/27 Javascript
AngularJS 过滤与排序详解及实例代码
2016/09/14 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
laravel5.4+vue+element简单搭建的示例代码
2017/08/29 Javascript
vue2+el-menu实现路由跳转及当前项的设置方法实例
2017/11/07 Javascript
基于JavaScript中字符串的match与replace方法(详解)
2017/12/04 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
[51:10]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
在Python程序中进行文件读取和写入操作的教程
2015/04/28 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
2018/04/27 Python
Python简直是万能的,这5大主要用途你一定要知道!(推荐)
2019/04/03 Python
Puppeteer使用示例详解
2019/06/20 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
Python一键安装全部依赖包的方法
2019/08/12 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
PyQT5速成教程之Qt Designer介绍与入门
2020/11/02 Python
什么是Oracle的后台进程background processes?都有哪些后台进程?
2012/04/26 面试题
会计电算化专业毕业生推荐信
2013/12/24 职场文书
小学语文教学经验交流材料
2014/06/02 职场文书
学校学雷锋活动总结
2014/06/26 职场文书
婚内分居协议书范文
2014/11/26 职场文书
领导干部考核评语
2015/01/04 职场文书
大学生党员自我评价
2015/03/04 职场文书
装修安全责任协议书
2016/03/22 职场文书
简单了解 MySQL 中相关的锁
2021/05/25 MySQL
解决Jenkins集成SonarQube遇到的报错问题
2021/07/15 Java/Android
python基础之错误和异常处理
2021/10/24 Python