javascript
JS事件冒泡
JavaSciprt事件中有兩個(gè)很重要的特性:事件冒泡以及目標(biāo)元素。
事件冒泡: 當(dāng)一個(gè)元素上的事件被觸發(fā)的時(shí)候,比如說鼠標(biāo)點(diǎn)擊了一個(gè)按鈕,同樣的事件將會(huì)在那個(gè)元素的所有祖先元素中被觸發(fā)。這 一過程被稱為事件冒泡;這個(gè)事件從原始元素開始一直冒泡到DOM樹的最上層。
目標(biāo)元素: 任何一個(gè)事件的目標(biāo)元素都是最開始的那個(gè)元素,在我們的這個(gè)例子中也就是按鈕,并且它在我們的元素對(duì)象中以屬性的形 式出現(xiàn)。使用事件代理的話我們可以把事件處理器添加到一個(gè)元素上,等待一個(gè)事件從它的子級(jí)元素里冒泡上來,并且可以很方便地得知這個(gè)事件是從哪個(gè)元素開始 的。
事件的冒泡和捕獲
捕獲是從上級(jí)元素到下級(jí)元素,冒泡是從下級(jí)元素到上級(jí)元素.
在IE中,每個(gè)元素和window對(duì)象都有兩個(gè)方法:attachEvent()和detachEvent()。attachEvent()用來給 一個(gè)事件附加事件處理函數(shù)。而detachEvent()用來將事件處理函數(shù)分離出來。例如:
JS代碼
var fnClick = function() {alert(“Clicked!”);}var oDiv = document.getElementById(“div1”);oDiv.attachEvent(“onclick”, fnClick);oDiv.detachEvent(“onclick”, fnClick);?
事件的冒泡有什么好處呢?想象一下現(xiàn)在我們有一個(gè)10列、100行的HTML表格,你希望在用戶點(diǎn)擊 表格中的某一單元格的時(shí)候做點(diǎn)什么。比如說我有一次就需要讓表格中的每一個(gè)單元格在被點(diǎn)擊的時(shí)候變成可編輯狀態(tài)。如果把事件處理器加到這1000個(gè)單元格 會(huì)產(chǎn)生一個(gè)很大的性能問題,并且有可能導(dǎo)致內(nèi)存泄露甚至是瀏覽器的崩潰。相反地,使用事件代理的話,你只需要把一個(gè)事件處理器添加到table元素上就可 以了,這個(gè)函數(shù)可以把點(diǎn)擊事件給截下來,并且判斷出是哪個(gè)單元格被點(diǎn)擊了。
代碼很簡(jiǎn)單,我們所要關(guān)心的只是如何檢測(cè)目標(biāo)元素而已。比方說我們有一個(gè) table元素,ID是“report”,我們?yōu)檫@個(gè)表格添加一個(gè)事件處理器以調(diào)用editCell函數(shù)。editCell函數(shù)需要判斷出傳到table 來的事件的目標(biāo)元素??紤]到我們要寫的幾個(gè)函數(shù)中都有可能用到這一功能,所以我們把它單獨(dú)放到一個(gè)名為getEventTarget的函數(shù)中:
JS代碼
function getEventTarget(e) { e = e || window.event; return e.target || e.srcElement; }?
e這個(gè)變量表示的是一個(gè)事件對(duì)象,我們只需要寫一點(diǎn)點(diǎn)跨瀏覽器的代碼來返回 目標(biāo)元素,在IE里目標(biāo)元素放在srcElemtn屬性或event.toElement屬性中,而在其它瀏覽器里則是target或event.relatedTarget屬性。
接下來就是editCell函數(shù)了,這個(gè)函數(shù)調(diào)用到了 getEventTarget函數(shù)。一旦我們得到了目標(biāo)元素之后,剩下的事情就是看看它是否是我們所需要的那個(gè)元素了。
JS代碼
function editCell(e) { var target = getEventTarget(e); if(target.tagName.toLowerCase() === ‘td’) { // DO SOMETHING WITH THE CELL } }?
在editCell函數(shù)中,我們通過檢查目標(biāo)元素標(biāo)簽名稱的方法來確定它是 否是一個(gè)表格的單元格。這種檢查也許過于簡(jiǎn)單了點(diǎn);如果它是這個(gè)目標(biāo)元素單元格里的另一個(gè)元素呢?我們需要為代碼做一點(diǎn)小小的修改以便于其找出父級(jí)的td 元素。如果說有些單元格不需要被編輯怎么辦呢?此種情況下我們可以為那些不可編輯的單元格添加一個(gè)指定的樣式名稱,然后在把單元格變成可編輯狀態(tài)之前先檢 查它是否不包含那個(gè)樣式名稱。選擇總是多樣化的,你只需找到適合你應(yīng)用程序的那一種。
事件冒泡的優(yōu)點(diǎn)和缺點(diǎn):
1.那些需要?jiǎng)?chuàng)建的以及駐留在內(nèi)存中的事件處理器少了。
這是很重要的一點(diǎn),這樣我們就提高了性能,并降低了崩潰的風(fēng)險(xiǎn)。
2.在DOM更新后無須重新綁定事件處理器了。
如果你的頁(yè)面是動(dòng)態(tài)生成的,比如說通過Ajax,你不再需要在元素被載入或 者卸載的時(shí)候來添加或者刪除事件處理器了。
潛在的問題也許并不那么明顯,但是一旦你注意到這些問題,你就可 以輕松地避免它們:你的事件管理代碼有成為性能瓶頸的風(fēng)險(xiǎn),所以盡 量使它能夠短小精悍。
不是所有的事件都能冒泡
blur、focus、load和unload不能像其它事件一樣冒泡。事 實(shí)上blur和focus可以用事件捕獲而非事件冒泡的方法獲得(在IE之外的其它瀏覽器中)。
需要注意的是:
如果你的代碼處理mousemove事件的話你遇上性能瓶頸的風(fēng)險(xiǎn)可就大了,因?yàn)閙ousemove事件觸發(fā)非常頻繁。而mouseout則因?yàn)槠?怪異的表現(xiàn)而變得很難用事件代理來管理。
消除冒泡事件的方法:
阻止JavaScript事件冒泡傳遞(cancelBubble 、stopPropagation)
下面的一段代碼即可以很好的解釋是么是冒泡效果,什么叫消除冒泡效果
HTML代碼
<!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”> <head> <title> 阻止JavaScript事件冒泡傳遞(cancelBubble 、stopPropagation)</title> <meta name=”keywords” content=”JavaScript,事件冒泡,cancelBubble,stopPropagation” /> <script type=”text/javascript”> function doSomething (obj,evt) { alert(obj.id); var e=(evt)?evt:window.event; //判斷瀏覽器的類型,在基于ie內(nèi)核的瀏覽器中的使用cancelBubble if (window.event) { e.cancelBubble=true; } else { //e.preventDefault(); //在基于firefox內(nèi)核的瀏覽器中支持做法stopPropagation e.stopPropagation(); } } </script> </head> <body> <div id=”parent1″ onclick=”alert(this.id)” style=”width:250px;background-color:yellow”> <p>This is parent1 div.</p> <div id=”child1″ onclick=”alert(this.id)” style=”width:200px;background-color:orange”> <p>This is child1.</p> </div> <p>This is parent1 div.</p> </div> <br /> <div id=”parent2″ onclick=”alert(this.id)” style=”width:250px;background-color:cyan;”> <p>This is parent2 div.</p> <div id=”child2″ onclick=”doSomething(this,event);” style=”width:200px;background-color:lightblue;”> <p>This is child2. Will bubble.</p> </div> <p>This is parent2 div.</p> </div> </body> </html>?
把代碼直接復(fù)制后,打開當(dāng)點(diǎn)擊child1時(shí)不僅會(huì)彈出 child1, 對(duì)話框還會(huì)彈出 parent1,這就是冒泡事件的;但是單擊chile2只會(huì)彈出child2卻不會(huì)彈出 parent2,這便是應(yīng)用了阻止冒泡事件的特效的效果。
轉(zhuǎn)載于:https://www.cnblogs.com/mrma/p/3891770.html
總結(jié)
- 上一篇: 一种基于openflow的虚拟化层软件f
- 下一篇: tomcat 启动时 Initializ