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 相关文章推荐
Prototype使用指南之enumerable.js
Jan 10 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
Sep 20 Javascript
JavaScript中使用Substring删除字符串最后一个字符
Nov 03 Javascript
Jquery.Form 异步提交表单的简单实例
Mar 03 Javascript
基于BootStrap Metronic开发框架经验小结【一】框架总览及菜单模块的处理
May 12 Javascript
适用于手机端的jQuery图片滑块动画
Dec 09 Javascript
JS中关于正则的巧妙操作
Aug 31 Javascript
jQuery获取随机颜色的实例代码
May 21 jQuery
layui 实现table翻页滚动条位置保持不变的例子
Sep 05 Javascript
javascript实现点亮灯泡特效示例
Oct 15 Javascript
vue中的循环对象属性和属性值用法
Sep 04 Javascript
给原生html中添加水印遮罩层的实现示例
Apr 02 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数据代码
2008/06/05 PHP
javascript,php获取函数参数对象的代码
2011/02/03 PHP
用php的ob_start来生成静态页面的方法分析
2011/03/09 PHP
tp5(thinkPHP5框架)使用DB实现批量删除功能示例
2019/05/28 PHP
PHP中echo与print区别点整理
2021/03/09 PHP
各浏览器中querySelector和querySelectorAll的实现差异分析
2012/05/23 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
js检测判断日期大于多少天的方法
2015/05/04 Javascript
JavaScript截断字符串的方法
2015/07/15 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
详解用Webpack与Babel配置ES6开发环境
2019/03/12 Javascript
原生js实现trigger方法示例代码
2019/05/22 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
JavaScript中如何调用Java方法
2020/09/16 Javascript
解决vue init webpack 下载依赖卡住不动的问题
2020/11/09 Javascript
[02:33]DOTA2英雄基础教程 司夜刺客
2013/12/04 DOTA
[27:28]Ti4 冒泡赛第二天 iG vs NEWBEE 1
2014/07/15 DOTA
简化Python的Django框架代码的一些示例
2015/04/20 Python
python计算时间差的方法
2015/05/20 Python
win10下安装Anaconda的教程(python环境+jupyter_notebook)
2019/10/23 Python
pygame实现贪吃蛇游戏(下)
2019/10/29 Python
Python 异步协程函数原理及实例详解
2019/11/13 Python
Python实现企业微信机器人每天定时发消息实例
2020/02/25 Python
个人简历自我评价八例
2013/10/31 职场文书
金融专业应届生求职信
2013/11/02 职场文书
妇产医师自荐信
2014/01/29 职场文书
八一建军节感言
2014/02/28 职场文书
企业文化理念标语
2014/06/10 职场文书
民事授权委托书范文
2014/08/02 职场文书
西柏坡导游词
2015/02/05 职场文书
酒店前台岗位职责
2015/04/16 职场文书
面试通知短信
2015/04/20 职场文书
当幸福来敲门英文观后感
2015/06/01 职场文书
导游词之丽江普济寺
2019/10/22 职场文书
python中 .npy文件的读写操作实例
2022/04/14 Python