JavaScript Event学习第七章 事件属性


Posted in Javascript onFebruary 07, 2010

当我们想去读一读关于Event的一些资料时,常常会湮没在大量的属性里面,这些属性其中的大多数不能良好的运行在大多数的浏览器。这里有event的兼容性列表。
我不打算给这些属性列个表,因为那些情况实在是太让人晕头了,而且对你的学习也不会有一点点的帮助。在写5段代码前我先要问关于浏览器的5个问题。
1、event的类型(type)是什么?
2、哪一个HTML元素是event的目标呢?
3、哪些键在event发生时被按下了?
4、哪个鼠标键在Event发生时被按下了?
5、在Event发生时鼠标的位置在哪?
最后一个问题我在这里做了非常详尽的解答。
请注意这些代码我做了非常严谨的对象检查。我首先创建跨浏览器的的对事件的访问,然后在使用每一个属性前都做了浏览器支持性的检查。

1、event的类型(type)是什么?
这是一个跨浏览器的有标准答案的问题:使用type属性就可以查看其属性:

function doSomething(e) { 
if (!e) var e = window.event; 
alert(e.type); 
}

2、哪一个HTML元素是event的目标呢?
W3C/Netscape说:target。不对,微软说,是srcElement。这两个属性都返回event发生时的HTML元素。

function doSomething(e) { 
var targ; 
if (!e) var e = window.event; 
if (e.target) targ = e.target; 
else if (e.srcElement) targ = e.srcElement; 
if (targ.nodeType == 3) // defeat Safari bug 
targ = targ.parentNode; 
}

最后两行的代码专门针对Safari的。如果event发生在一个包含文本(text)的元素上,这个文本节点(text node)而不是元素本身就成为了event的目标。因此我们要检查如果目标的nodetype是3(文本节点)。如果是我们就把它移动到父节点上,HTML元素。
即使event被捕获或者冒泡了(bubbles up),target/srcElement属性也依然是最早发生event的元素。
其他的target
还有很多targeting的属性。我在Event Order这篇文章里讨论了currentTarget,在Mouse event这篇文章里讨论了relatedTarget,fromElement和toElement。

3、哪些键在event发生时被按下了?
这个问题相对简单一些。首先从keyCode属性得到该键的代码(a=65)。当你得到了键值以后,你可以通过String.fromCharCode()方法知道实际的键值,如果必要的话。

function doSomething(e) { 
var code; 
if (!e) var e = window.event; 
if (e.keyCode) code = e.keyCode; 
else if (e.which) code = e.which; 
var character = String.fromCharCode(code); 
alert('Character was ' + character); 
}

这里有一些地方可能会造成键盘事件比较难用。比如,kepress事件触发的时间和使用者按下键的时间一样长。然而,大多数浏览器里面keydown的触发时间也和按下的时间一样长。我不确定这是不是一个好的想法,但是就是那样的。

4、哪个鼠标键在Event发生时被按下了?
这里有两个属性可以知道哪个鼠标键被按下了:which和button。请注意这些属性通常不一定在click上起作用。为了保险的探测哪个鼠标键被按下,你最好使用mousedown和mouseup事件。
which是一个古老的Netscape属性。鼠标左键的值是1,中键(滚轮)的值是2,右键的值是3。除了支持上比较薄弱以外没有什么问题,事实上也经常用来检测鼠标按键。
现在button属性能被很好的识别。W3C的标准值如下:
左键 0
中键 1
右键 2
微软的标准值如下:
左键 1
中键 4
右键 2
毫无疑问的微软的标准比W3C的好。0可以表示没有键按下,其他都是不合理的。
另外,只有在微软的模型中按键的值是可以合并使用的,比如5就代表“左键和中键”一起按下。不仅IE6不支持合并,w3c的的模型在理论上也是不能完成的:你永远也不知道左键是不是被按下了。
所以在我看来w3c在定义button上有严重的失误。

右击
幸运的是,通常你想知道右键是否被点击。因为W3C和微软恰好在这个问题上给button的定义值是2,所以你依然可以检测右击。

function doSomething(e) { 
var rightclick; 
if (!e) var e = window.event; 
if (e.which) rightclick = (e.which == 3); 
else if (e.button) rightclick = (e.button == 2); 
alert('Rightclick: ' + rightclick); // true or false 
}

需要注意的是,Macs通常只有一个键,Mozilla给Ctrl-Click的button的值定义为2,所以Ctrl-Click也会打开菜单。ICab 还不支持鼠标button属性,所以你在Opera里面还不能检测右击。
5、在Event发生时鼠标的位置在哪?
鼠标位置这个问题相当的严峻。虽然有不少于6对鼠标坐标的属性,但是仍然没有一个可靠的跨浏览器的方法能找到鼠标的坐标。
下面是这6组坐标:
1、clientX,clientY
2、layerX,layerY
3、offsetX,offsetY
4、pageX,pageY
5、screenX,screenY
6、x,y
我曾经在这里解释过pageX/Y和clientX/Y的问题。
screenX和screenY是唯一一对跨浏览器兼容的属性。他们给出鼠标在整个电脑屏幕上的坐标。不幸的是,仅仅这个信息是远远不够的:你永远也不需要知道鼠标在屏幕的位置--好吧,或者你想在当前的鼠标位置放置一个新的窗口。
其他的三对属性也不重要,看这里的描述。
正确的代码
下面的代码能够正确的检测鼠标的坐标

function doSomething(e) { 
var posx = 0; 
var posy = 0; 
if (!e) var e = window.event; 
if (e.pageX || e.pageY) { 
posx = e.pageX; 
posy = e.pageY; 
} 
else if (e.clientX || e.clientY) { 
posx = e.clientX + document.body.scrollLeft 
+ document.documentElement.scrollLeft; 
posy = e.clientY + document.body.scrollTop 
+ document.documentElement.scrollTop; 
} 
// posx and posy contain the mouse position relative to the document 
// Do something with this information 
}

原文在这里:http://www.quirksmode.org/js/events_properties.html

大家多指教 我的twitter:@rehawk

Javascript 相关文章推荐
jQuery 性能优化手册 推荐
Feb 23 Javascript
封装了一个js图片轮换效果的函数
Sep 28 Javascript
解决ueditor jquery javascript 取值问题
Dec 30 Javascript
js实现随屏幕滚动的带缓冲效果的右下角广告代码
Sep 04 Javascript
解析Node.js异常处理中domain模块的使用方法
Feb 16 Javascript
Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放的解决方案
Sep 15 Javascript
基于angular实现三级联动的生日插件
May 12 Javascript
JavaScript设计模式之策略模式详解
Jun 09 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
Jan 02 jQuery
基于Angularjs-router动态改变Title值的问题
Aug 30 Javascript
浅谈vue加载优化策略
Mar 19 Javascript
基于JavaScript获取base64图片大小
Oct 18 Javascript
JavaScript Event学习第六章 事件的访问
Feb 07 #Javascript
JavaScript Event学习第五章 高级事件注册模型
Feb 07 #Javascript
JavaScript Event学习第四章 传统的事件注册模型
Feb 07 #Javascript
JavaScript Event学习第三章 早期的事件处理程序
Feb 07 #Javascript
JavaScript Event学习第二章 Event浏览器兼容性
Feb 07 #Javascript
JavaScript Event事件学习第一章 Event介绍
Feb 07 #Javascript
jQuery库与其他JS库冲突的解决办法
Feb 07 #Javascript
You might like
攻克CakePHP系列一 连接MySQL数据库
2008/10/22 PHP
浅析application/x-www-form-urlencoded和multipart/form-data的区别
2014/06/22 PHP
验证坐标在某坐标区域内php代码
2016/10/08 PHP
php获取当前url地址的方法小结
2017/01/10 PHP
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
jQuery的deferred对象使用详解
2011/08/20 Javascript
javascript 进阶篇2 CSS XML学习
2012/03/14 Javascript
javascript判断office版本示例
2014/04/11 Javascript
JavaScript通过事件代理高亮显示表格行的方法
2015/05/27 Javascript
跟我学习javascript的函数和函数表达式
2015/11/16 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
js获取json中key所对应的value值的简单方法
2020/06/17 Javascript
详解如何在vue中使用sass
2017/06/21 Javascript
AngularJS实现的根据数量与单价计算总价功能示例
2017/12/26 Javascript
对node.js中render和send的用法详解
2018/05/14 Javascript
详解swipe使用及竖屏页面滚动方法
2018/06/28 Javascript
Vue表单控件绑定图文详解
2019/02/11 Javascript
微信小程序文字显示换行问题
2019/07/28 Javascript
vue跳转页面的几种方法(推荐)
2020/03/26 Javascript
Python字符串详细介绍
2015/05/09 Python
python实现实时监控文件的方法
2016/08/26 Python
tensorflow saver 保存和恢复指定 tensor的实例讲解
2018/07/26 Python
Python 使用Numpy对矩阵进行转置的方法
2019/01/28 Python
基于django ManyToMany 使用的注意事项详解
2019/08/09 Python
Python 仅获取响应头, 不获取实体的实例
2019/08/21 Python
Python hashlib常见摘要算法详解
2020/01/13 Python
python 引用传递和值传递详解(实参,形参)
2020/06/05 Python
python爬虫要用到的库总结
2020/07/28 Python
python使用yaml 管理selenium元素的示例
2020/12/01 Python
ProForm英国站点:健身房和健身器材网上商店
2019/06/05 全球购物
酒店管理专业学生求职信
2013/09/27 职场文书
房屋继承公证书
2014/04/10 职场文书
房地产广告策划方案
2014/05/15 职场文书
个人思想政治总结
2015/03/05 职场文书
mongodb清除连接和日志的正确方法分享
2021/09/15 MongoDB