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 相关文章推荐
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
Jan 22 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
Aug 26 Javascript
jquery得到iframe src属性值的方法
Sep 25 Javascript
javascript实现分栏显示小技巧附图
Oct 13 Javascript
node.js中的fs.open方法使用说明
Dec 17 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
Nov 13 Javascript
javascript单页面手势滑屏切换原理详解
Mar 21 Javascript
jQuery实现二维码扫描功能
Jan 09 Javascript
node使用Koa2搭建web项目的方法
Oct 17 Javascript
使用jquery DataTable和ajax向页面显示数据列表的方法
Aug 09 jQuery
layui前端框架之table表数据的刷新方法
Aug 17 Javascript
详解Node.js一行命令上传本地文件到服务器
Apr 22 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冒泡排序算法的深入理解
2013/06/09 PHP
php实现监听事件
2013/11/06 PHP
jquery关于图形报表的运用实现代码
2011/01/06 Javascript
Jquery 例外被抛出且未被接住原因介绍
2013/09/04 Javascript
基于jquery的网站幻灯片切换效果焦点图代码
2013/09/15 Javascript
javascript间隔刷新的简单实例
2013/11/14 Javascript
jQuery中:gt选择器用法实例
2014/12/29 Javascript
原生js图片轮播效果实现代码
2016/10/19 Javascript
express文件上传中间件Multer详解
2016/10/24 Javascript
JS实现简单的二元方程计算器功能示例
2017/01/03 Javascript
JS去除字符串中空格的方法
2017/02/14 Javascript
关于jQuery EasyUI 中刷新Tab选项卡后一个页面变形的解决方法
2017/03/02 Javascript
jQuery实现简单的手风琴效果
2020/04/17 jQuery
Javascript ES6中对象类型Sets的介绍与使用详解
2017/07/17 Javascript
Vue写一个简单的倒计时按钮功能
2018/04/20 Javascript
Vue组件通信中非父子组件传值知识点总结
2019/12/05 Javascript
在Vue中实现随hash改变响应菜单高亮
2020/03/09 Javascript
JavaScript碰撞检测原理及其实现代码
2020/03/12 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
2020/06/22 Javascript
Vant Weapp组件踩坑:picker的初始赋值解决
2020/11/12 Javascript
Python实现控制台进度条功能
2016/01/04 Python
Python 专题一 函数的基础知识
2017/03/16 Python
Python实现合并同一个文件夹下所有txt文件的方法示例
2018/04/26 Python
Python3 修改默认环境的方法
2019/02/16 Python
python读出当前时间精度到秒的代码
2019/07/05 Python
Python中list循环遍历删除数据的正确方法
2019/09/02 Python
基于matplotlib xticks用法详解
2020/04/16 Python
Feelunique美国:欧洲大型的在线美妆零售电商
2018/11/04 全球购物
乡镇安全生产月活动总结
2015/05/08 职场文书
田径运动会广播稿
2015/08/19 职场文书
高中地理教学反思
2016/02/19 职场文书
《兰兰过桥》教学反思
2016/02/20 职场文书
情况说明书格式及范文
2019/06/24 职场文书
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
2021/06/04 Oracle
Python字典和列表性能之间的比较
2021/06/07 Python
实战 快速定位MySQL的慢SQL
2022/03/22 MySQL