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 相关文章推荐
JS解密入门 最终变量劫持
Jun 25 Javascript
jquery下拉select控件操作方法分享(jquery操作select)
Mar 25 Javascript
简单对比分析JavaScript中的apply,call与this的使用
Dec 04 Javascript
漫谈JS引擎的运行机制 你应该知道什么
Jun 15 Javascript
Bootstrap图片轮播组件Carousel使用方法详解
Oct 20 Javascript
vue2.0父子组件及非父子组件之间的通信方法
Jan 21 Javascript
JavaScript编写一个贪吃蛇游戏
Mar 09 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
Aug 25 Javascript
angularjs实现猜大小功能
Oct 23 Javascript
详解如何运行vue项目
Apr 15 Javascript
javascript函数式编程基础
Sep 15 Javascript
javascript之Object.assign()的痛点分析
Mar 03 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实现根据数组某个键值大小进行排序的方法
2018/03/13 PHP
PHP5中使用mysqli的prepare操作数据库的介绍
2019/03/18 PHP
关于实现代码语法标亮 dp.SyntaxHighlighter
2007/02/02 Javascript
javascript控制Div层透明属性由浅变深由深变浅逐渐显示
2013/11/12 Javascript
移动节点的jquery代码
2014/01/13 Javascript
jquery实现浮动的侧栏实例
2015/06/25 Javascript
HTML5 canvas 9绘制图片实例详解
2016/09/06 Javascript
bootstrap导航条实现代码
2016/12/28 Javascript
js实现随机数字字母验证码
2017/06/19 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
2018/09/26 Javascript
详解vue 不同环境配置不同的打包命令
2019/04/07 Javascript
js键盘事件实现人物的行走
2020/01/17 Javascript
Vue事件处理原理及过程详解
2020/03/11 Javascript
[01:11:15]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[04:32]玩具屠夫中文语音节选
2020/08/23 DOTA
使用beaker让Facebook的Bottle框架支持session功能
2015/04/23 Python
Python实现将目录中TXT合并成一个大TXT文件的方法
2015/07/15 Python
关于pip的安装,更新,卸载模块以及使用方法(详解)
2017/05/19 Python
Python实现字符串格式化输出的方法详解
2017/09/20 Python
python with提前退出遇到的坑与解决方案
2018/01/05 Python
Python实现判断并移除列表指定位置元素的方法
2018/04/13 Python
查看django版本的方法分享
2018/05/14 Python
Python统计学一数据的概括性度量详解
2020/03/03 Python
django处理select下拉表单实例(从model到前端到post到form)
2020/03/13 Python
慕尼黑山地运动、户外服装和体育用品专家:Sporthaus Schuster
2019/08/27 全球购物
如何开启linux的ssh服务
2013/06/03 面试题
公司领导推荐信
2013/11/12 职场文书
大学校庆邀请函
2014/01/11 职场文书
工程造价专业大学生职业规划范文
2014/03/09 职场文书
语文高效课堂实施方案
2014/05/03 职场文书
党员领导干部民主生活会批评与自我批评发言
2014/09/28 职场文书
介绍信格式样本
2015/05/05 职场文书
2016年度师德标兵先进事迹材料
2016/02/26 职场文书
如何利用js在两个html窗口间通信
2021/04/27 Javascript
SQL Server表分区删除详情
2021/10/16 SQL Server
Win11 Beta 22621.601 和 22622.601今日发布 KB5017384修复内容汇总
2022/09/23 数码科技