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 相关文章推荐
popdiv
Jul 14 Javascript
不一样的文字闪烁 轮番闪烁
Nov 11 Javascript
js通过地址栏给action传值(中文乱码全是问号)
May 02 Javascript
通过js简单实现将一个文本内容转译成加密文本
Oct 22 Javascript
JS基于myFocus库实现各种功能的tab选项卡切换效果
Sep 19 Javascript
jquery实现静态搜索功能(可输入搜索文字)
Mar 28 jQuery
Angular中响应式表单的三种更新值方法详析
Aug 22 Javascript
使用Angular CLI生成路由的方法
Mar 24 Javascript
axios 处理 302 状态码的解决方法
Apr 10 Javascript
JavaScript中变量提升与函数提升经典实例分析
Jul 26 Javascript
JS实现小米轮播图
Sep 21 Javascript
Vue过滤器,生命周期函数和vue-resource简单介绍
Jan 12 Vue.js
由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开发工具及资源收藏
2007/01/02 PHP
php调用MySQL存储过程的方法集合(推荐)
2013/07/03 PHP
PHP合并数组+号和array_merge的区别
2015/06/25 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
javascript预加载图片、css、js的方法示例介绍
2013/10/14 Javascript
常用js字符串判断方法整理
2013/10/18 Javascript
禁止拷贝网页内容的js代码
2014/01/22 Javascript
Chrome下ifame父窗口调用子窗口的问题示例探讨
2014/03/17 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
Bootstrap轮播插件简单使用方法介绍
2016/06/21 Javascript
layui表格内容溢出的解决方法
2019/09/06 Javascript
JS实现压缩上传图片base64长度功能
2019/12/03 Javascript
vue2路由基本用法实例分析
2020/03/06 Javascript
在antd Form表单中select设置初始值操作
2020/11/02 Javascript
Vue 实现可视化拖拽页面编辑器
2021/02/01 Vue.js
python 实现网上商城,转账,存取款等功能的信用卡系统
2016/07/15 Python
python数据挖掘需要学的内容
2019/06/23 Python
python使用minimax算法实现五子棋
2019/07/29 Python
PyTorch 对应点相乘、矩阵相乘实例
2019/12/27 Python
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
定制别致的瑜伽垫:Sugarmat
2019/06/21 全球购物
英语硕士生求职简历的自我评价
2013/10/15 职场文书
兼职学生的自我评价
2013/11/24 职场文书
党员思想汇报范文
2013/12/30 职场文书
演讲稿祖国在我心中
2014/05/04 职场文书
个人工作主要事迹
2014/05/08 职场文书
迟到检讨书2000字(精选篇)
2014/10/07 职场文书
小学三八妇女节活动总结
2015/02/06 职场文书
管理人员岗位职责
2015/02/14 职场文书
幼儿园开学通知
2015/04/24 职场文书
聊聊JS ES6中的解构
2021/04/29 Javascript
浅谈golang package中init方法的多处定义及运行顺序问题
2021/05/06 Golang
Redis监控工具RedisInsight安装与使用
2022/03/21 Redis
win10更新失败无限重启解决方法
2022/04/19 数码科技