Javascript 事件流和事件绑定

浏览器中的事件流意味着页面上可有不仅一个,甚至多个元素响应同一个事件。而这一个或多个元素响应事件发生的先后顺序在各个浏览器(主要针对IE和Netscape)上是不同的。

冒泡型事件(Dubbed Bubbling)

IE上的解决方案就是冒泡型事件(Dubbed Bubbling)。冒泡型事件的基本思想是,事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。

示例(1):

示例(1)的XHTML代码结构:

<span>
     <a href=”#1″ id=”link0″>点击我触发冒泡型事件流</a>
</span>

这个示例里我同时给span和a标签绑定了click事件,大家看到了,我们点击这个a标签,一次点击(click)同时触发了两个元素a和span的事件。先触发的是绑定给a标签的click事件,然后触发的是span标签的click事件。也就是前面提到的“页面上可有不仅一个,甚至多个元素响应同一个事件”和“事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发”。

这个示例里我们点击的第一目标是a标签这个链接,它就是前面提到的“最特定的事件目标”,然后才是span这个相对“不特定的事件目标”。再看看我的XHTML代码结构,你会发现a标签包含在span标签中,也就是说span是a标签的父节点,如果大家还不是很清晰的知道他们之间的关系,让我们看看下面的这个DOM树的结构图:

事件触发的顺序是从最特定的目标,沿着DOM树不断的向上触发click事件,就像气泡从下一直上冒的过程一样。“冒泡型”也就是这么得来的,也很形象。这里要说明的是,由于我只给a和span绑定了click事件,所以“冒”到span就到顶了,如果你也给包含他们的p标签还有document绑定click事件,这个冒泡的过程就会一直延续到document的事件触发才结束。

另外要说明的是,在IE5.5中冒泡的最高层DOM节点为document,IE6中则可以支持html节点。在Mozllia1.0及之后的版本也支持冒泡,而它则更可以冒到window窗口对象。

捕获型事件(Event Capturing)

相对IE4.0,Netscape4.0则使用的是捕获型事件的解决方案。这个事件触发的过程则正好和冒泡相反——在捕获型事件中,事件从最不精确的对象(document对象)开始触发,然后到最精确的对象。还是前面的示例,不过现在换由捕获型事件触发(当然你需要在Netscape或Firefox中测试)。

示例(2):

示例(2)的XHTML代码结构:

<span>
     <a href=”#1″ id=”link1″>点击我触发捕获型事件流</a>
</span>

事件触发的循序正好跟前面的冒泡相反,这里我就不赘述了。

DOM 事件流

这个事件流则是W3C制定一个标准规范,它同时支持两种事件流模式,不过是先发生捕获型事件流,再发生冒泡型事件流。

DOM事件流最独特的是,它支持文本节点也触发事件(IE中这不支持)。不过说实话,我现在还看不出来让文本节点支持事件有什么作用。

最后要说的是,根据最近大家在开发的实践过程中的运用,我们一般都采取冒泡型的事件流触发方式,这点我们的IE做的比较成功。至于原因,我想你可以通过上面的解释可以看出,毕竟我们给元素触发事件,肯定是希望从我们最希望先触发(从最精确的)的那个开始。而DOM的先捕获后冒泡我觉得只能用让我很疑惑来形容我的感受。因为如果按照DOM的事件流,我们的事件要被触发2次,而我们一般都只会选择一个类型的事件流,值希望触发一次,很难理解当初W3C是怎么想的?!一个字——晕!可能我的理解能力有限,不过这是我的真是感受。

事件处理函数/监听函数

这里我不想做过多的介绍,我们知道在IE里使用attachEvent(”NAME_OF_EVENT_HANDLER”, fnHandler)给元素绑定事件,而在支持DOM事件流的浏览器里,则使用addEventListener(”NAME_OF_EVENT_HANDLER”, fnHandler, isCapture)。前面我控制FIREFOX中触发捕获事件流,就是通过设置isCapture(ture:捕获;false:冒泡)做到的。还有就是我们传统element.onclick或者element['on'+eventName],这个是所有浏览器都支持的事件绑定的监听器,而且我测试的结果XP下的IE6~8、Firefox2.0~3.5、Safari4.0、Opera9.6.4、Chrome2.0.180都是以冒泡的事件流触发的。更老的浏览器我就没有测试过了,不过根据《Pro Javascript Techniques》里介绍,老的浏览器使用onclick这样的事件绑定,触发的也是冒泡事件流。如果你有兴趣可以淘下那些古董浏览器,测试一番。不过还是有不支持冒泡的事件的,下面我们就讲讲。

那些事件是支持冒泡,那些不支持?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjwwsx.html