程序员人生 网站导航

JavaScript Event学习第八章:事件的顺序

栏目:jscript时间:2014-03-09 03:16:33
在第一章中我提到一个初次看起来可能不是那么好理解的是一个问题:“如果一个元素和他的父元素对于同样的事件都有事件处理程序,那么哪个会首先执行呢?”毫无疑问,看是什么浏览器。

基本问题很简单。假设你的一个元素包含在另外一个元素中。

-----------------------------------<BR>| element1 |<BR>| ------------------------- |<BR>| |element2 | |<BR>| ------------------------- |<BR>| |<BR>-----------------------------------<BR>

这两个元素都有onclick事件处理程序。如果用户在element2上面单击那么在元素2和元素1上都触发了单击事件。但是哪个事件先发生呢?哪个事件处理程序会先执行呢?换句话说,事件顺序(event order)是什么呢?

两种模式
毫无疑问的,Netscape和微软在过去那段很糟糕的日子里都做出了自己的决定。
Netscape说element1先发生的。这叫事件捕获(event capturing)。
微软觉得element2先发生的。这叫事件冒泡(event bubbling)。
这两种事件顺序刚好相反。IE只支持事件冒泡。Mozilla,Opera 7和Konqueror两种都支持。早一些的Opear和iCab浏览器两个都不支持。

事件捕获
当你使用事件捕获的时候

| |<BR>---------------| |-----------------<BR>| element1 | | |<BR>| --------- --| |----------- |<BR>| |element2 / | |<BR>| ------------------------- |<BR>| Event CAPTURING |<BR>-----------------------------------<BR>

element1的事件处理程序会先执行,element2后执行。

事件冒泡
但你使用事件冒泡的时候

/ <BR>---------------| |-----------------<BR>| element1 | | |<BR>| ---------- -| |----------- |<BR>| |element2 | | | |<BR>| ------------------------- |<BR>| Event BUBBLING |<BR>-----------------------------------<BR>

element2的事件处理程序会先执行,element1的事件处理程序后执行。

W3C模式
W3C决定在这场战争中保持重力。在W3C事件模型中任何事件发生都是首先被捕获直到到达目标元素,然后再冒泡。

| | / <BR>-----------------| |--| |-----------------<BR>| element1 | | | | |<BR>| ----------- --| |--| |----------- |<BR>| |element2 / | | | |<BR>| -------------------------------- |<BR>| W3C event model |<BR>------------------------------------------<BR>

作为设计师的你,可以随意选择把事件处理程序注册在捕获还是冒泡阶段。通过之前高级模式里面介绍的addEventListener()方法就可以完成。如果最后一个参数是true那么就设置成为事件捕获,如果是false就设置为事件冒泡。

假设你这样写

element1.addEventListener('click',doSomething2,true)<BR>element2.addEventListener('click',doSomething,false)<BR>

如果用户在element2上单击就会发生下面的事情:
1、click事件发生在捕获阶段。这样看来,如果element2的任何一个父元素有onclick事件处理程序那么都会执行。
2、事件在element1上发现了doSomething2(),那么就会执行它。
3、事件向下传递直到目标本身,再没有其他的捕获阶段程序了。事件转而进入冒泡阶段然后就会执行doSomething(),也就是element2注册在冒泡阶段的事件处理程序。
4、事件再向上传递再检查是否有父元素在冒泡阶段设置事件处理程序。这里没有,所以什么也不会发生。

反过来:

element1.addEventListener('click',doSomething2,false)<BR>element2.addEventListener('click',doSomething,false)<BR>

现在如果用户在element2上面点击就会发生:
1、事件click发生在捕获阶段。事件会查找element2的父元素是否有在捕获阶段注册事件处理程序,在这里没有。
2、事件向下传递直到目标本身。然后开始冒泡阶段,执行dosomething(),这个是注册在element2冒泡阶段的事件处理程序。
3、事件继续向上传递然后检查是否有父元素在冒泡阶段注册了事件处理程序。
4、事件发现了element1.然后doSomething2()就被执行了。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐