摘要:如圖使用事件捕獲模式注冊事件監(jiān)聽對最外層,中間層,最內(nèi)層分別用捕獲模式注冊事件監(jiān)聽,我們上面說了,如果使用捕獲模式,那么第三個參數(shù)應(yīng)該是,否則則是冒泡模式,如果不聲明,默認(rèn)為冒泡模式。
來源: 個人博客
想必好多童鞋都有直接復(fù)制粘貼event.preventDefault() 或者event.stopPropagation() 的經(jīng)歷,但是為什么這樣做不甚了解,今天我們的目的就是要徹底搞懂這一區(qū)別。
javascript中的“事件傳播”模式為了徹底弄清楚它們之間的區(qū)別,我不得不要先說一下javascript中兩種事件傳播模式:
- 捕獲模式(capturing) - 冒泡模式(bubbling)
捕獲模式又稱為“滴流模式”(trickling),個人認(rèn)為滴流模式更好理解,滴流就是“從上向下”,而冒泡就是“從下向上”,好了,先記住這兩種模式的特點。
同時你還要記住,這兩種模式是為了干什么的?
這兩種模式就是為了一點:決定html中“元素”(比如div, p, button)接收到事件的“順序”!當(dāng)然接收到事件的順序不同,自然事件監(jiān)聽函數(shù)被觸發(fā)的順序就不同了,于是間接地就出現(xiàn)了監(jiān)聽函數(shù)被執(zhí)行順序的不同。
所以。。
捕獲模式當(dāng)事件發(fā)生時,該事件首先被最外層元素接受到,然后依次向內(nèi)層元素傳播。(從上向下)
冒泡模式當(dāng)事件發(fā)生時,該事件首先被最內(nèi)層元素接受到,然后依次向外層元素傳播。(從下向上)
順便提一句,以前網(wǎng)景公司主推捕獲模式而微軟則偏向于冒泡模式,不過兩者都是W3C DOM事件標(biāo)準(zhǔn)(2000)。
IE9以下僅僅支持冒泡模式,但是IE9+以及現(xiàn)在的主流瀏覽器都支持兩種模式了。
聲明方式用哪種事件傳播方式完全是我們自己說了算的,我們可以使用
addEventListener(type, listener, useCapture)
來注冊事件處理方式,以及以何種傳播模式進(jìn)行。
例子我們可以對上述代碼添加一些樣式,這樣在網(wǎng)頁中更直觀。
outerMostMiddle click
如圖:
使用事件捕獲模式注冊事件監(jiān)聽對最外層,中間層,最內(nèi)層分別用“捕獲”模式注冊事件監(jiān)聽,我們上面說了,如果使用捕獲模式,那么addEventListener第三個參數(shù)應(yīng)該是true,否則則是冒泡模式,如果不聲明,默認(rèn)為冒泡模式。
var outerElement = document.getElementById("outerMost"); var middleElement = document.getElementById("middle"); var innerElement = document.getElementById("innerMost"); outerElement.addEventListener("click", function () { console.log("trigger outermost div"); }, true); middleElement.addEventListener("click", function () { console.log("trigger middle div"); }, true); innerElement.addEventListener("click", function () { console.log("trigger innermost button"); }, true);
我們點擊中間層Middle字樣,如圖:
可以看到,事件觸發(fā)從外向里進(jìn)行,如果大家把a(bǔ)ddEventListener中第三個參數(shù)改為false或者留空,點擊middle字樣,則會得到相反的結(jié)果,大家可以自己試一下。
preventDefault 及 stopPropagation函數(shù)區(qū)別終于到了談一談preventDefault 和 stopPropagation了,大家可能注意到了,我上面的例子中沒有涉及到點擊click鏈接,為什么呢?大家可以試一下,點擊click會發(fā)生什么?它會又立即跳轉(zhuǎn)到了當(dāng)前頁面(因為我們href是一個空連接,這是鏈接元素的一個默認(rèn)特性),雖然我們的監(jiān)聽函數(shù)被執(zhí)行了,但是有時候我們不想這個默認(rèn)特性被執(zhí)行,比如,我們可能想在監(jiān)聽函數(shù)里面改變div的背景顏色等等,這樣如果這個鏈接元素a默認(rèn)特性的存在就會立即“刷新”了該頁面,讓我們的改變背景顏色無法進(jìn)行。
所以為了“阻止”元素的“默認(rèn)特性”,所以事件對象中有了一個preventDefault方法,如下:
innerElement.addEventListener("click", function (event) { event.preventDefault(); console.log("trigger innermost button"); }, true);
這樣我們點擊click就會得到:
trigger outermost div trigger middle div trigger innermost button
那么stopPropagation呢?
向上面這種情況,如果當(dāng)你點擊click的時候,只想出發(fā)綁定在click上的監(jiān)聽函數(shù),而不想觸發(fā)“傳播鏈”上的其他函數(shù),那么則使用stopPropagation。
注意:你在那個事件監(jiān)聽函數(shù)中使用event.stopPropagation();那么傳播鏈就會終止,向上面這個例子,因為我們使用的是捕獲模式,即使我們添加了:
innerElement.addEventListener("click", function (event) { event.preventDefault(); event.stopPropagation(); console.log("trigger innermost button"); }, true);
依然會得到和上面一樣的結(jié)果,為什么呢?因為捕獲模式是由外往里傳播,我們只是在a這里阻止了繼續(xù)像里傳播,因為沒有更里的元素了,所以結(jié)果一樣,為了更好地演示,我們可以把捕獲模式改為冒泡模式如下:
var outerElement = document.getElementById("outerMost"); var middleElement = document.getElementById("middle"); var innerElement = document.getElementById("innerMost"); outerElement.addEventListener("click", function (event) { console.log("trigger outermost div"); }); middleElement.addEventListener("click", function () { console.log("trigger middle div"); }); innerElement.addEventListener("click", function (event) { event.preventDefault(); event.stopPropagation(); console.log("trigger innermost button"); });
這樣點擊click,就只得到了一條log:
trigger innermost buttonreturn false;
最后說一下return false; 這是jQuery中提供,比如:
$("#innermost").on("click", function () { return false; })
它幫我們同時做了:
- event.preventDefault(); - event.stopPropagation();
這兩個工作,你可以看做是一種快捷方式,但是你在原生javascript中的監(jiān)聽回調(diào)函數(shù)中寫return false; 是沒有任何用的。比如:
innerElement.addEventListener("click", function (event) { return false; });
只是jQuery提供的一種特性。
來源:個人博客
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88117.html
摘要:在這段代碼中,實際上就是閉包函數(shù)。定時器例子假設(shè),某個事件處理程序使用設(shè)置了一個間隔的重復(fù)定時器。在下一個間隔,即處,第一個定時器代碼仍在運行,同時在隊列中已經(jīng)有了一個定時器代碼的實例。結(jié)果是,在這個時間點上的定時器代碼不會被添加到隊列中。 函數(shù) 匿名函數(shù)立即調(diào)用 (function (){alert(1)}()) function的左圓括號是必須的 函數(shù)的調(diào)用 1,作為函數(shù)的調(diào)用,2...
摘要:簡單的門面模式實例事件綁定函數(shù)門面模式的作用是將復(fù)雜的接口進(jìn)行包裝,變成一個便于使用的接口。還是以事件相關(guān)為例,事件綁定中還有兩個常用的分別是和。 門面模式是什么,與其我去用笨拙的語言去解釋,不如看下面這張圖,曾經(jīng)在網(wǎng)上很火的一張圖片,說的是一位兒子為他的爸媽設(shè)置的電腦桌面。 showImg(http://segmentfault.com/img/bVcgHm); 有了這些起好名字...
摘要:歡迎光臨小弟博客我的博客原文中的各種區(qū)別小節(jié)參考普通添加事件和事件綁定的事件監(jiān)聽與捕獲和冒泡和的區(qū)別 相信大家在DOM的實際開發(fā)與學(xué)習(xí)過程中,肯定也遇到不少需要比較的東西,這里我主要列比較以下幾點,更多的區(qū)別和總結(jié),希望想到和遇到的朋友給我留言哦。 clientHeight/scrollHeight/offsetHeight defer vs async 事件模型-捕獲/目標(biāo)/冒泡...
摘要:一和的作用和區(qū)別觸發(fā)被選元素上的指定事件以及事件的默認(rèn)行為比如表單提交不會引起事件比如表單提交的默認(rèn)行為觸發(fā)所有匹配元素的指定事件只觸發(fā)第一個匹配元素的指定事件會冒泡不會冒泡二被點擊了作用看一源碼觸發(fā)事件,是自定義事件的額外參數(shù)源碼行解析本 showImg(https://segmentfault.com/img/remote/1460000019375685); 一、$().trig...
閱讀 1784·2021-09-22 15:25
閱讀 1332·2019-08-29 12:34
閱讀 1950·2019-08-26 13:57
閱讀 3226·2019-08-26 10:48
閱讀 1470·2019-08-26 10:45
閱讀 823·2019-08-23 18:23
閱讀 764·2019-08-23 18:01
閱讀 1975·2019-08-23 16:07