關於JavaScript/jQuery事件冒泡

來源:互聯網
上載者:User

JavaSciprt事件中有兩個很重要的特性:事件冒泡以及目標元素。</p><p>事件冒泡: 當一個元素上的事件被觸發的時候,比如說滑鼠點擊了一個按鈕,同樣的事件將會在那個元素的所有祖先元素中被觸發。這一過程被稱為事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層。</p><p>目標元素: 任何一個事件的目標元素都是最開始的那個元素,在我們的這個例子中也就是按鈕,並且它在我們的元素對象中以屬性的形式出現。使用事件代理的話我們可以把事件處理器添加到一個元素上,等待一個事件從它的子級元素裡冒泡上來,並且可以很方便地得知這個事件是從哪個元素開始的。</p><p>事件的冒泡和捕獲</p><p>捕獲是從上階項目到下級元素,冒泡是從下級元素到上階項目.</p><p>在IE中,每個元素和window對象都有兩個方法:attachEvent()和detachEvent()。attachEvent()用來給一個事件附加事件處理函數。而detachEvent()用來將事件處理函數分離出來。Eg.</p><p>var fnClick = function() {<br />alert(“Clicked!”);<br />}<br />var oDiv = document.getElementById(“div1”);<br />oDiv.attachEvent(“onclick”, fnClick);<br />oDiv.detachEvent(“onclick”, fnClick);事件的冒泡有什麼好處呢?</p><p>想象一下現在我們有一個10列、100行的HTML表格,你希望在使用者點擊表格中的某一儲存格的時候做點什麼。比如說我有一次就需要讓表格中的每一個儲存格在被點擊的時候變成可編輯狀態。如果把事件處理器加到這1000個儲存格會產生一個很大的效能問題,並且有可能導致記憶體泄露甚至是瀏覽器的崩潰。相反地,使用事件代理的話,你只需要把一個事件處理器添加到table元素上就可以了,這個函數可以把點擊事件給截下來,並且判斷出是哪個儲存格被點擊了。</p><p>代碼很簡單,我們所要關心的只是如何檢測目標元素而已。比方說我們有一個 table元素,ID是“report”,我們為這個表格添加一個事件處理器以調用editCell函數。editCell函數需要判斷出傳到table 來的事件的目標元素。考慮到我們要寫的幾個函數中都有可能用到這一功能,所以我們把它單獨放到一個名為getEventTarget的函數中:</p><p>function getEventTarget(e) {<br /> e = e || window.event;<br /> return e.target || e.srcElement;<br />}e這個變數表示的是一個事件對象,我們只需要寫一點點跨瀏覽器的代碼來返回目標元素,在IE裡目標元素放在srcElemtn屬性或event.toElement屬性中,而在其它瀏覽器裡則是target或event.relatedTarget屬性。</p><p>接下來就是editCell函數了,這個函數調用到了 getEventTarget函數。一旦我們得到了目標元素之後,剩下的事情就是看看它是否是我們所需要的那個元素了。</p><p>function editCell(e) {<br /> var target = getEventTarget(e);<br /> if(target.tagName.toLowerCase() === 'td') {<br /> // DO SOMETHING WITH THE CELL<br /> }<br />}在editCell函數中,我們通過檢查目標元素標籤名稱的方法來確定它是否是一個表格的儲存格。這種檢查也許過於簡單了點;如果它是這個目標元素儲存格裡的另一個元素呢?我們需要為代碼做一點小小的修改以便於其找出父級的td 元素。如果說有些儲存格不需要被編輯怎麼辦呢?此種情況下我們可以為那些不可編輯的儲存格添加一個指定的樣式名稱,然後在把儲存格變成可編輯狀態之前先檢查它是否不包含那個樣式名稱。選擇總是多樣化的,你只需找到適合你應用程式的那一種。</p><p>事件冒泡的優點和缺點:</p><p>1.那些需要建立的以及駐留在記憶體中的事件處理器少了。</p><p>這是很重要的一點,這樣我們就提高了效能,並降低了崩潰的風險。</p><p>2.在DOM更新後無須重新綁定事件處理器了。</p><p>如果你的頁面是動態產生的,比如說通過Ajax,你不再需要在元素被載入或者卸載的時候來添加或者刪除事件處理器了。</p><p>潛在的問題也許並不那麼明顯,但是一旦你注意到這些問題,你就可以輕鬆地避免它們:你的事件管理代碼有成為效能瓶頸的風險,所以盡量使它能夠短小精悍。</p><p>不是所有的事件都能冒泡</p><p>blur、focus、load和unload不能像其它事件一樣冒泡。事實上blur和focus可以用事件捕獲而非事件冒泡的方法獲得(在IE之外的其它瀏覽器中)。</p><p>需要注意的是:</p><p>如果你的代碼處理mousemove事件的話你遇上效能瓶頸的風險可就大了,因為mousemove事件觸發非常頻繁。而mouseout則因為其怪異的表現而變得很難用事件代理來管理。</p><p>如何避免事件冒泡:</p><p>1.方法</p><p>2.方法</p><p>在IE下解決問題很簡單,用onMouseEnter、 onMouseLeave來代替onMouseOver、onMouseOut就行了,他們的作用基本相同,前者不會發生冒泡。但是 firefox下沒有這兩個事件.</p><p>3.方法:</p><p>window.event.cancelBubble = true (IE) event.stopPropagation() event.preventDefault() (Firefox)</p><p>阻止jQuery事件冒泡</p><p>jQuery對DOM的事件觸發具有冒泡特性。有時利用這一特性可以減少重複代碼,但有時候我們又不希望事件冒泡。這個時候就要阻止 jQuery.Event冒泡。</p><p>在jQuery.Event的文檔中的開頭得知,jQuery.Event對象是符合W3C標準的一個事件對象,同時jQuery.Event免去了檢查相容IE的步驟。</p><p>jQuery.Event提供了一個非常簡單的方法來阻止事件冒泡:event.stopPropagation();</p><p>$("p").click(function(event){<br /> event.stopPropagation();<br /> // do something<br />})但是這個方法對使用live綁定的事件沒有作用,需要一個更簡單的方法阻止事件冒泡:return false;</p><p>$(this).after("Another paragraph!");<br />return false; });

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.