javascript 事件机制 与 jQuery.Bind
2010-05-08 23:30 BAsil 阅读(2760) 评论(1) 编辑 收藏 举报W3C DOM Level2的事件模型规范中,事件在DOM树中的传播过程(从根节点到目标节点)被分为了两个阶段:捕捉(Capture)和冒泡(Bubbling),而事件在传递的过程中需要先经历Capture Phrase后经历Bubble Phrase 。在firefox下,我们可以用target.addEventListener(type, listener, useCapture),第三个参数指定是否为Capture;但IE不支持捕获,而且jQuery也不支持Capture(不过我觉得Bubbling足够了)。因此后面的讨论主要在Bubbling阶段。首先看一下IE下实现事件模型的代码。
请在IE8运行以下代码(只能在ie8下运行)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #panelGrandPa,#panelPaPa,#panelSon { border:1px solid #320213;} </style> </head> <body> <div id="panelGrandPa" style="width:300px;height:200px;" > <div id="panelPaPa" style="width:200px;height:100px;" > <div id="panelSon" style="width:100px;height:50px;" > </div> </div> </div> <script> function click() { alert(event.srcElement.id); event.data = event.data || 1; alert("click function has fired " + event.data + " times"); event.data = parseInt(event.data) + 1; } function clickSon() { alert("I am son"); click(); } function clickGrandPa() { alert("I am GrandPa"); click(); } document.getElementById("panelGrandPa").onclick = clickGrandPa; document.getElementById("panelSon").onclick = clickSon; </script> </body> </html>
注意传统element.onclick或者element['on'+eventName],这个是所有浏览器都支持的事件绑定的监听器,但由于上述代码使用了event.srcElement.id,因此只能在IE8下运行。下面看一下在firefox下的使用,这里我们采用了符合W3C DOM的target.addEventListener(type, listener, useCapture),另外使用了event.target.id。
请在firefox,chrome下运行以下代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #panelGrandPa,#panelPaPa,#panelSon { border:1px solid #320213;} </style> <head> <body> <div id="panelGrandPa" style="width:300px;height:200px;" > <div id="panelPaPa" style="width:200px;height:100px;" > <div id="panelSon" style="width:100px;height:50px;" > </div> </div> </div> <script> function click(e) { alert(e.target.id); e.data = e.data || 1; alert("click function has fired " + e.data + " times"); e.data = parseInt(e.data) + 1; } function clickSon(e) { alert("I am son"); click(e); } function clickGrandPa(e) { alert("I am GrandPa"); click(e); } document.getElementById("panelGrandPa").addEventListener("click", clickGrandPa, false); document.getElementById("panelSon").addEventListener("click", clickSon, false); </script> </body> </html>
那么在jQuery中我们是怎么处理的呢
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.js"></script> <title></title> <style> #panelGrandPa,#panelPaPa,#panelSon { border:1px solid #320213;} </style> <head> <body> <div id="panelGrandPa" style="width:300px;height:200px;" > <div id="panelPaPa" style="width:200px;height:100px;" > <div id="panelSon" style="width:100px;height:50px;" > </div> </div> </div> <script> function click(e) { alert(e.target.id); e.data = e.data || 1; alert("click function has fired " + e.data + " times"); e.data = parseInt(e.data) + 1; } function clickSon(e) { alert("I am son"); click(e); } function clickGrandPa(e) { alert("I am GrandPa"); click(e); } $("#panelGrandPa").bind("click", clickGrandPa); $("#panelSon").bind("click", clickSon); </script> </body> </html>
这里使用了e.target,不过和之前的非jQuery版本不同,此处的e(event)是调用了jQuery.event.fix(event),也就是说jQuery的处理让event更加透明。不过这段代码的运行还是有问题的,就是click function的fire time 始终为1,也就是说e.data的值无法在多个事件函数里传递,这个我暂时还没有找到原因;不过希望通过进一步探究jQuery源代码找到问题原因及解决思路,本文旨在说明javascript 事件机制 与 jQuery.Bind的简单用法,就此搁笔了,关于前面抛出的问题,也请各位不吝赐教。