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

浙公网安备 33010602011771号