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 写的个性导航菜单
Dec 24 Javascript
javascript 学习笔记(八)javascript对象
Apr 12 Javascript
json原理分析及实例介绍
Nov 29 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
Mar 24 Javascript
javascript鼠标滑动评分控件完整实例
May 13 Javascript
jQuery 判断图片是否加载完成方法汇总
Aug 10 Javascript
jquery ajax异步提交表单数据的方法
Oct 27 jQuery
vue使用自定义icon图标的方法
May 14 Javascript
angularjs实现对表单输入改变的监控(ng-change和watch两种方式)
Aug 29 Javascript
史上最为详细的javascript继承(推荐)
May 18 Javascript
js如何验证密码强度
Mar 18 Javascript
分享8个JavaScript库可更好地处理本地存储
Oct 12 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读取和编写XML DOM的实现代码
2011/02/03 PHP
浅析php单例模式
2014/11/25 PHP
PHP中把数据库查询结果输出为json格式简单实例
2015/04/09 PHP
Yii中CArrayDataProvider和CActiveDataProvider区别实例分析
2016/03/02 PHP
Laravel 类和接口注入相关的代码
2019/10/15 PHP
JS获取scrollHeight问题想到的标准问题
2007/05/27 Javascript
2010年最佳jQuery插件整理
2010/12/06 Javascript
利用js实现遮罩以及弹出可移动登录窗口
2013/07/08 Javascript
js冒泡法和数组转换成字符串示例代码
2013/08/14 Javascript
jQuery中parents()和parent()的区别分析
2014/10/28 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
2015/07/27 Javascript
基于javascript bootstrap实现生日日期联动选择
2016/04/07 Javascript
限制只能输入数字的实现代码
2016/05/16 Javascript
基于JQuery实现分隔条的功能
2016/06/17 Javascript
BootStrap中按钮点击后被禁用按钮的最佳实现方法
2016/09/23 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
2016/11/17 Javascript
angular2路由切换改变页面title的示例代码
2017/08/23 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
vue中使用sessionStorage记住密码功能
2018/07/24 Javascript
vue防止花括号{{}}闪烁v-text和v-html、v-cloak用法示例
2019/03/13 Javascript
python实现12306火车票查询器
2017/04/20 Python
Python字符串处理实现单词反转
2017/06/14 Python
Python实现计算圆周率π的值到任意位的方法示例
2018/05/08 Python
django解决跨域请求的问题详解
2019/01/20 Python
Python django框架应用中实现获取访问者ip地址示例
2019/05/17 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
详解Python IO口多路复用
2020/06/17 Python
浅谈python 类方法/静态方法
2020/09/18 Python
详解BeautifulSoup获取特定标签下内容的方法
2020/12/07 Python
html5 canvas-2.用canvas制作一个猜字母的小游戏
2013/01/07 HTML / CSS
英国电子产品购物网站:TobyDeals
2018/07/30 全球购物
L*SPACE官网:比基尼、泳装和度假服装
2019/03/18 全球购物
BannerBuzz加拿大:在线定制横幅印刷、广告和标志
2020/03/10 全球购物
公共事业管理本科生求职信
2013/10/07 职场文书
个人先进材料范文
2014/12/30 职场文书
七年级英语教学反思
2016/02/15 职场文书