JavaScript应用核心:事件处理概述(1)(4)
捕获型事件模型与冒泡型事件模型的应用场合
标准事件模型为我们提供了两种方案,可能很多朋友分不清这两种不同模型有啥好处,为什么不只采取一种模型。这里抛开IE浏览器讨论(IE只有一种,没法选择)什么情况下适合哪种事件模型。
1. 捕获型应用场合
捕获型事件传递由最不精确的祖先元素一直到最精确的事件源元素,传递方式与操作系统中的全局快捷键与应用程序快捷键相似。当一个系统组合键发生时,如果注
册了系统全局快捷键监听器,该事件就先被操作系统层捕获,全局监听器就先于应用程序快捷键监听器得到通知,也就是全局的先获得控制权,它有权阻止事件的进
一步传递。所以捕获型事件模型适用于作全局范围内的监听,这里的全局是相对的全局,相对于某个顶层结点与该结点所有子孙结点形成的集合范围。
例如你想作全局的点击事件监听,相对于document结点与document下所有的子结点,在某个条件下要求所有的子结点点击无效,这种情况下冒泡模型就解决不了了,而捕获型却非常适合,可以在最顶层结点添加捕获型事件监听器,伪码如下:
- function globalClickListener(event) {
- if(canEventPass == false) {
- //取消事件进一步向子结点传递和冒泡传递
- event.stopPropagation();
- //取消浏览器事件后的默认执行
- event.preventDefault();
- }
- }
这样一来,当canEventPass条件为假时,document下所有的子结点click注册事件都不会被浏览器处理。
2. 冒泡型的应用场合
可以说我们平时用的都是冒泡事件模型,因为IE只支持这模型。这里还是说说,在恰当利用该模型可以提高脚本性能。在元素一些频繁触发的事件中,如onmousemove,onmouseover,onmouseout,如果明确事件处理后没必要进一步传递,那么就可以大胆的取消它。
此外,对于子结点事件监听器的处理会对父层监听器处理造成负面影响的,也应该在子结点监听器中禁止事件进一步向上传递以消除影响。
综合案例分析
最后结合下面HTML代码作分析:
- <body onclick="alert('current is body');">
- <div id="div0" onclick="alert('current is '+this.id)">
- <div id="div1" onclick="alert('current is '+this.id)">
- <div id="div2" onclick="alert('current is '+this.id)">
- <div id="event_source"
- onclick="alert('current is '+this.id)"
- style="height:200px;width:200px;background-color:red;">
- </div>
- </div>
- </div>
- </div>
- </body>
HTML运行后点击红色区域,这是最里层的DIV,根据上面说明,无论是DOM标准还是IE,直接写在html里的监听处理函数是事件冒泡传递时调用的,由最里层一直往上传递,所以会先后出现:
- current is event_source
- current is div2
- current is div1
- current is div0
- current is body
添加以下片段:
- var div2 = document.getElementById('div2');
- EventUtil.addHandler(div2, 'click', function(event){
- event = EventUtil.getEvent(event);
- EventUtil.stopPropagation(event);
- }, false);
当点击红色区域后,根据上面说明,在泡冒泡处理期间,事件传递到div2后被停止传递了,所以div2上层的元素收不到通知,所以会先后出现:
- current is event_source
- current is div2
在支持DOM标准的浏览器中,添加以下代码:
- document.body.addEventListener('click', function(event){
- event.stopPropagation();
- }, true);
以上代码中的监听函数由于是捕获型传递时被调用的,所以点击红色区域后,虽然事件源是ID为event_source的元素,但捕获型选传递,从最顶层开始,body结点监听函数先被调用,并且取消了事件进一步向下传递,所以只会出现current is body。
原文链接:http://cssrainbow.cn/tutorials/javascript/1027.html






