jquery之浏览器的事件模型(DOM 0级事件模型)
----------
DOM 0级事件模型大概是大多数web开发者在页面上所采用的事件模型。在这个事件模型下,事件处理程序是通过把函数实例的引用指派到DOM元素的属性而声明的。定义这些属性用来处理特定类型的事件。例如,指派函数到onclick属性用来处理点击事件。指派函数到onmouseover属性用来处理mouseover事件,而元素支持这些事件类型。
浏览器也允许指定事件处理程序的函数体,作为DOM元素的HTML里的特性值,从而提供创建事件处理程序的简便方法。
如例:
<html> <head> <title>DOM Level 0 Events Example</title> <mce:script type="text/javascript" src="../scripts/jquery-1.2.1.js" mce_src="scripts/jquery-1.2.1.js"></mce:script> <mce:script type="text/javascript"><!-- $(function(){ $('#vstar')[0].onmouseover = function(event){ say('Whee!'); } }); function say(text){ $('#console').append('<div>' + new Date() + ' ' + text + '</div>'); } // --></mce:script> </head> <body> <img id="vstar" src="vstar.jpg" mce_src="vstar.jpg" onclick="say('vroom vroom!');"/> <div id="console"></div> </body> </html>
这个示例采用两种风格声明事件处理函数: 声明在脚本控制下和在标记特性里。
请注意:
上例中,我们利用onclick特性,在<img>元素标记里声明点击事件处理程序:
onclick="say('Vroom vroom!');"
这可能让人误以为say()函数成为元素的点击事件处理程序,但实际上并不是那样。如果通过特性标记来声明处理程序,匿名函数就会利用特性的值作为函数体而自动创建。通过特性标记声明处理程序,操作执行结果相当于如下代码(假设imageElement是图像元素的引用):
imageElement.onclick = function(event){ say('Vroom vroom!'); }
注意这个生成的函数使用了event,而在上面例子中,声明在脚本控制下的事件处理函数也用了event参数。
===
关于Event实例
在大多数浏览器里,当触发事件处理程序时,名为Event的类实例作为第一个参数传递到处理程序。一直占据主流地位的IE浏览器,却以专门的方式处理事情,它把Event实例指派到window对象的名为event的属性。为了处理这个矛盾,我们将经常看到事件处理程序的第一个语句如下所示:
if(!event) event = window.event;
这个语句消除了矛盾。它首先进行对象检测,检查event参数是否为undefined(或null)。如果是那样的话就把window的event属性值指派到event参数。在这个语句之后可以引用event参数,而不用再关心怎样使它在处理程序中变得可用。当然还有其他异同之处,这里不再解释。
===
事件冒泡
当触发DOM树里元素上的事件时,浏览器的事件处理机制会检查在那个元素上是否已经建立特定的事件处理程序。如果是,就调用处理程序。但到这儿事情还远远没有结束呢。在目标元素获得机会处理事件之后,事件模型检查目标元素的父元素,看是否为同类型事件建立了处理程序。如果是,则也调用父元素的处理程序。在这之后,再检查其父元素,然后父元素,然后父元素...持续不停直到DOM树的顶部。因为事件处理向上传播像水里的泡泡,所以把这个过程称为事件冒泡。
===
影响事件传播的语义
可能有些场合我们想阻止事件沿着DOM树向上传播;不管什么理由,可以通过在Event实例上已提供的机制来防止事件向上传播。对于标准兼容的浏览器,调用Event实例的stopPropagation()方法可以中止事件往祖先层次传播。对于IE浏览器,则将Event实例中名为cancelBubble的属性设置为true。