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 JSON的解析方式
Jul 25 Javascript
javascript qq右下角滑出窗口 sheyMsg
Mar 21 Javascript
js location.replace与location.reload的区别
Sep 08 Javascript
利用js的Node遍历找到repeater的一个字段实例介绍
Apr 25 Javascript
JavaScript中的slice()方法使用详解
Jun 06 Javascript
如何制作幻灯片(代码分享)
Jan 06 Javascript
js中常用的Math方法总结
Jan 12 Javascript
Vue2单一事件管理组件通信
May 09 Javascript
javascript修改浏览器title方法 JS动态修改浏览器标题
Nov 30 Javascript
详解js跨域请求的两种方式,支持post请求
May 05 Javascript
Node.js的进程管理的深入理解
Jan 09 Javascript
jQuery实现飞机大战小游戏
Jul 05 jQuery
由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 echo 输出字符串函数详解
2010/05/13 PHP
PHP中header和session_start前不能有输出原因分析
2013/01/11 PHP
php结合js实现点击超链接执行删除确认操作
2014/10/31 PHP
ThinkPHP自动完成中使用函数与回调方法实例
2014/11/29 PHP
php使用CURL伪造IP和来源实例详解
2015/01/15 PHP
PHP日期函数date格式化UNIX时间的方法
2015/03/19 PHP
Mootools 1.2教程 类(一)
2009/09/15 Javascript
js函数获取html中className所在的内容并去除标签
2013/09/08 Javascript
Javascript解析URL方法详解
2014/12/05 Javascript
javascript创建函数的20种方式汇总
2015/06/23 Javascript
javascript禁止访客复制网页内容的实现代码
2015/08/05 Javascript
jQuery+ajax实现文章点赞功能的方法
2015/12/31 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
2016/01/15 Javascript
浅谈JavaScript对象的创建方式
2016/06/13 Javascript
BootStrap网页中代码显示用法详解
2016/10/21 Javascript
koa2使用ejs和nunjucks作为模板引擎的使用
2018/11/27 Javascript
[01:02:06]LGD vs Mineski Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
点球小游戏python脚本
2018/05/22 Python
tensorflow 获取模型所有参数总和数量的方法
2018/06/14 Python
解决pycharm运行出错,代码正确结果不显示的问题
2018/11/30 Python
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
python读取图片任意范围区域
2019/01/23 Python
python使用多线程编写tcp客户端程序
2019/09/02 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
python实现吃苹果小游戏
2020/03/21 Python
使用Python将图片转正方形的两种方法实例代码详解
2020/04/29 Python
Django serializer优化类视图的实现示例
2020/07/16 Python
Java提供了哪些企业应用编程接口
2015/02/13 面试题
介绍一下如何优化MySql
2016/12/20 面试题
中间件的定义
2016/08/09 面试题
减负增效提质方案
2014/05/23 职场文书
公司领导班子召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
工作经历证明书范文
2014/11/02 职场文书
Python Numpy库的超详细教程
2022/04/06 Python
vue实现省市区联动 element-china-area-data插件
2022/04/22 Vue.js