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