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 相关文章推荐
利用Ext Js生成动态树实例代码
Sep 08 Javascript
复制Input内容的js代码_支持所有浏览器,修正了Firefox3.5以上的问题
Jun 21 Javascript
javascript动态添加样式(行内式/嵌入式/外链式等规则)
Jun 24 Javascript
js数组去重的常用方法总结
Jan 24 Javascript
基于javascript实现彩票随机数生成(简单版)
Apr 17 Javascript
JS封装的选项卡TAB切换效果示例
Sep 20 Javascript
JS利用cookies设置每隔24小时弹出框
Apr 20 Javascript
AngularJs 延时器、计时器实例代码
Sep 16 Javascript
Node.JS段点续传:Nginx配置文件分段下载功能的实现方法
Mar 12 Javascript
深入了解JavaScript 的 WebAssembly
Jun 15 Javascript
layer弹出框确定前验证:弹出消息框的方法(弹出两个layer)
Sep 21 Javascript
ECharts transform数据转换和dataZoom在项目中使用
Dec 24 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入门
2006/10/09 PHP
php addslashes和mysql_real_escape_string
2010/01/24 PHP
php 文本文件的读取效率
2012/02/10 PHP
ThinkPHP框架实现session跨域问题的解决方法
2014/07/01 PHP
Ajax异步提交表单数据的说明及方法实例
2013/06/22 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
javascript(js)的小数点乘法除法问题详解
2014/03/07 Javascript
javascript正则表达式总结
2016/02/29 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
2016/09/06 Javascript
AngularJs入门教程之环境搭建+创建应用示例
2016/11/01 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
Node.js 回调函数实例详解
2017/07/06 Javascript
浅谈vue-cli 3.0.x 初体验
2018/04/11 Javascript
Vue iview-admin框架二级菜单改为三级菜单的方法
2018/07/03 Javascript
详解用JS添加和删除class类名
2019/03/25 Javascript
微信小程序获取地理位置及经纬度授权代码实例
2019/09/18 Javascript
微信小程序登陆注册功能的实现代码
2019/12/10 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
详解关于Vue单元测试的几个坑
2020/04/26 Javascript
python编程开发之日期操作实例分析
2015/11/13 Python
Python合并字典键值并去除重复元素的实例
2016/12/18 Python
python实现按任意键继续执行程序
2016/12/30 Python
对Python3中的print函数以及与python2的对比分析
2018/05/02 Python
windows下Python安装、使用教程和Notepad++的使用教程
2019/10/06 Python
使用pyecharts1.7进行简单的可视化大全
2020/05/17 Python
python产生模拟数据faker库的使用详解
2020/11/04 Python
Notino罗马尼亚网站:购买香水和化妆品
2019/07/20 全球购物
店长岗位职责
2013/11/21 职场文书
优秀士兵个人事迹材料
2014/01/19 职场文书
求职信范文怎么写
2014/01/29 职场文书
《钱学森》听课反思
2014/03/01 职场文书
农村婚礼主持词
2014/03/13 职场文书
庆祝教师节演讲稿
2014/09/03 职场文书
2014社会治安综合治理工作总结
2014/12/04 职场文书
MySQL 如何分析查询性能
2021/05/12 MySQL
Apache Hudi 加速传统的批处理模式
2022/04/24 Servers