JavaScript Event学习第五章 高级事件注册模型


Posted in Javascript onFebruary 07, 2010

W3C和微软都着力于发展自己的事件注册模型来取代Netscape的传统模型。虽然对于微软的模型我不是很感冒,但是w3c的还是不错的,除了这个鼠标定位 的问题。不过现在只有小部分浏览器支持。
W3C
W3C的DOM层面事件规范注意到了传统模式的问题。他对于你想在一个元素上绑定多个事件提供了一个很好的解决办法。
W3C事件注册模型的关键就是addEventListener()。你给他三个参数:事件类型,要执行的函数和一个布尔值(true或者false)我一会再解释。把我们熟知的doSomething()函数注册到一个元素的onclick事件上,你可以这样做:
element.addEventListener('click',doSomething,false)
这种模型的魅力在于我们可以想加多少监听就可以加多少。如果用我们之前的传统模式里面的例子,我们就可以写成这样:
element.addEventListener('click',startDragDrop,false)
element.addEventListener('click',spyOnUser,false)
当用户点击元素的时候两个事件处理程序都会执行。需要注意的是W3C标准不能确定哪个事件先执行。所以你也不能认为startDragDrop()就在spyOnUser()之前执行。
移除事件处理程序也是非常的简单,用removeEventListener()就行了。所以:
element.removeEventListener('click',spyOnUser,false)
就会移除第二个事件处理程序但是第一个不会发生变化。非常漂亮的程序,完全解决了传统模式下的问题。

匿名函数
在W3C模式下你依然可以使用匿名函数:

element.addEventListener('click',function () { 
this.style.backgroundColor = '#cc0000' 
},false)

true或者false
true或者false是addEventListener的最后一个参数,意思是你想让你的函数在捕获阶段还是冒泡阶段执行。如果你不确定,那就使用false(冒泡阶段)。
this
在JavaScript里this关键字通常指函数的所有者。如果this指向事件发生的HTML元素,那么一切都是那么的美好,你可以很简单的做很多事情。
不幸的是,虽然this非常的强大,但是如果你不是明确的知道他怎么运作的话使用起来还是比较难的。关于这个我在另一个地方有详细的讨论。
在w3c模型下他的运作和在传统模式下是一样的:他表示现在正在处理事件的HTML元素。
element.addEventListener('click',doSomething,false); 
another_element.addEventListener('click',doSomething,false); 
function doSomething() { 
this.style.backgroundColor = '#cc0000'; 
}

如果你把doSomething()注册在任意一个HTML元素的click实践上,那么当用户点击的时候这个元素的背景就会变成红色。

哪个事件处理程序被注册了呢?
现在这个W3C事件注册模式有一个问题就是你不知道一个元素都有哪些事件处理程序被注册了。在传统模式下面你可以:
alert(element.onclick)
你就可以看到哪些函数注册了,undefined就是没有函数注册在这个事件上。只是在最近的DOM Level 3事件中W3C才添加了一个eventListenerList来存储已经注册了的事件处理程序。因为太新了,鲜有浏览器支持。然而,问题已经解决了。
还好的是removeEventListener()不会因为你没有注册元素的某个事件而返回错误,所以你可以不用担心的使用removeEventLister()。
微软
微软也有一个事件注册模型。跟W3C的很像,但是有一个严重的缺陷。
注册一个事件处理程序,attach到一个元素:
element.attachEvent('onclick',doSomething)
或者,你需要两个事件处理程序:
element.attachEvent('onclick',startDragDrop)
element.attachEvent('onclick',spyOnUser)
移除一个也非常简单:
element.detachEvent('onclick',spyOnUser)

缺陷
跟W3C的相比较,微软有两个严重的问题:
、事件总是冒泡,没有被捕捉的可能。
、事件处理程序是被引用的,而不是拷贝的,所以this关键字总是指向window然后就一点用都没有。
这两个问题的结果就是如果一个事件冒泡了那么你是没有可能知道哪个元素在处理事件。在后面的事件顺序一章我会详细的解释。
而且微软的标准只被IE支持,也不能用来跨浏览器。就算你只是给windows浏览器写脚本也最好别用,因为冒泡问题会让事情变得不可收拾。
继续
如果你想继续学习,请看下一章。
原文地址:http://www.quirksmode.org/js/events_advanced.html
第一次翻译 大家多多包含 我的twitter:@rehawk

Javascript 相关文章推荐
jquery获取元素值的方法(常见的表单元素)
Nov 15 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
Dec 16 Javascript
JS简单实现动画弹出层效果
May 05 Javascript
原生JS实现仿淘宝网左侧商品分类菜单效果代码
Sep 10 Javascript
JS表单验证的代码(常用)
Apr 08 Javascript
jquery  实现轮播图详解及实例代码
Oct 12 Javascript
jQuery实现的手风琴侧边菜单效果
Mar 29 jQuery
AngularJS自定义指令详解(有分页插件代码)
Jun 12 Javascript
详解VUE 对element-ui中的ElTableColumn扩展
Mar 28 Javascript
AngularJs用户输入动态模板XSS攻击示例详解
Apr 21 Javascript
详解vue-cli脚手架中webpack配置方法
Aug 22 Javascript
微信小程序仿通讯录功能
Apr 09 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
jQuery学习7 操作JavaScript对象和集合的函数
Feb 07 #Javascript
jQuery 学习6 操纵元素显示效果的函数
Feb 07 #Javascript
You might like
Joomla下利用configuration.php存储简单数据
2010/05/19 PHP
php set_magic_quotes_runtime() 函数过时解决方法
2010/07/08 PHP
php中根据某年第几天计算出日期年月日的代码
2011/02/24 PHP
php汉字转拼音的示例
2014/02/27 PHP
PHP简单判断字符串是否包含另一个字符串的方法
2016/03/25 PHP
php将print_r处理后的数据还原为原始数组的解决方法
2016/11/02 PHP
laravel-admin的图片删除实例
2019/09/30 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
js 自定义个性下拉选择框示例
2013/08/20 Javascript
jquery实现的下拉和收缩效果示例
2014/08/21 Javascript
微信小程序 图片等比例缩放(图片自适应屏幕)
2016/11/16 Javascript
javascript实现根据函数名称字符串动态执行函数的方法示例
2016/12/28 Javascript
微信小程序 新建登录页并实现tabBar隐藏
2017/06/13 Javascript
Vue.js框架路由使用方法实例详解
2017/08/25 Javascript
mac中利用NVM管理不同node版本的方法详解
2017/11/08 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
jQuery zTree插件使用简单教程
2019/08/16 jQuery
微信小程序可滑动周日历组件使用详解
2019/10/21 Javascript
解决vue初始化项目一直停在downloading template的问题
2020/11/09 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
[08:53]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS 选手采访
2021/03/11 DOTA
Python映射拆分操作符用法实例
2015/05/19 Python
python通过zabbix api获取主机
2018/09/17 Python
python使用threading.Condition交替打印两个字符
2019/05/07 Python
对YOLOv3模型调用时候的python接口详解
2019/08/26 Python
通过字符串导入 Python 模块的方法详解
2019/10/27 Python
Python Pillow.Image 图像保存和参数选择方式
2020/01/09 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
html5 Canvas画图教程(9)—canvas中画出矩形和圆形
2013/01/09 HTML / CSS
什么是虚拟内存?虚拟内存有什么优势?
2016/02/09 面试题
优秀通讯员事迹材料
2014/01/28 职场文书
个人授权委托书范本
2014/04/03 职场文书
售房协议书
2014/08/19 职场文书
2014年人力资源工作总结
2014/11/19 职场文书
优秀党员主要事迹材料
2015/11/04 职场文书
python析构函数用法及注意事项
2021/06/22 Python