成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS 中的事件冒泡與捕獲

Rindia / 2031人閱讀

摘要:在之前是只支持事件冒泡,包括之后和目前主流的瀏覽器都同時支持兩種事件。中可以用來取消事件冒泡。

剛接觸 JS 的那個時候,啥也不懂,只想著如何利用 Google、百度到的函數(shù)來解決實際的問題,不會想到去一探究竟。

漸漸的,對 JS 的語言的不斷深入,有機會去了解一些原理性東西。最近在看 JQuery 源碼,感觸很多,總想著用原生的 JS 去實現(xiàn)自己的一個 JQuery 庫。說實在的,JQuery 里面很多函數(shù)和思路,是千百開源工作者長期的貢獻(xiàn),哪能是短時間就能消化的了。

最近再次碰到 addEventListener函數(shù)(MDN 上關(guān)于 addEventListener 的介紹,很詳細(xì)),由于之前并沒有弄懂第三個參數(shù)的含義,要么默認(rèn)值,要么手動設(shè)置成 false。這次看了不少文章,徹底把事件冒泡和捕獲弄懂。

什么事件冒泡與捕獲

事件冒泡與捕獲是 DOM 中事件傳播的兩種方式,比如說對于注冊了相同事件的兩個 DOM 元素(簡單點就是兩個 div,一里一外),當(dāng)點擊里層 div 的時候,這兩個事件誰先執(zhí)行。

冒泡事件,由里向外,最里層的元素先執(zhí)行,然后冒泡到外層。

捕獲事件,由外向里,最外層的元素先執(zhí)行,然后傳遞到內(nèi)部。

在 IE 9 之前是只支持事件冒泡,IE 9(包括 IE 9) 之后和目前主流的瀏覽器都同時支持兩種事件。

如何設(shè)置,只需修改 addEventListener的第三個參數(shù),true 為捕獲,false 為冒泡,默認(rèn)為冒泡。

舉個簡單的例子,

在上面這個例子中,事件是按照冒泡來執(zhí)行的,點擊里層的 in,會看到先 alert 的順序是先 "in" 后 "out",如果把事件改成捕獲,alert 的順序又不一樣了。

上面這個例子是捕獲事件的例子,點擊 in效果是不是不一樣呢?

之所以會有冒泡和捕獲事件(像 IE 9 之前的瀏覽器不支持捕獲事件,還真是反程序員),畢竟在實際中處理事情肯定有個先后順序,要么由里向外,要么由外向里,兩者都是必須的。

但有時候為了兼容 IE 9 以下版本的瀏覽器,都會把第三個參數(shù)設(shè)置成 false 或者默認(rèn)(默認(rèn)就是 false)。

進(jìn)一步理解冒泡和捕獲

現(xiàn)在已經(jīng)說清楚冒泡和捕獲,那么如果同時出現(xiàn)冒泡和捕獲會出現(xiàn)什么結(jié)果?

原來瀏覽器處理時間分為兩個階段,捕獲階段和冒泡階段,

先執(zhí)行捕獲階段,如果事件是在捕獲階段執(zhí)行的(true 情況),則執(zhí)行;

然后是冒泡階段,如果事件是在冒泡階段執(zhí)行的(false 情況),則執(zhí)行;

來看一看例子就知道了:

s1 s2 s3

這次我們設(shè)置三個 span,分別是 s1, s2, s3,然后設(shè)置 s1,s3 為冒泡執(zhí)行,s2 為捕獲執(zhí)行:

從運行的效果來看,點擊 s3,依次 alert s2 => s3 => s1,說明:

捕獲事件和冒泡事件同時存在的,而且捕獲事件先執(zhí)行,冒泡事件后執(zhí)行;

如果元素存在事件且事件的執(zhí)行時間與當(dāng)前邏輯一致(冒泡或捕獲),則執(zhí)行。

默認(rèn)事件取消與停止冒泡

當(dāng)然,有時候我們只想執(zhí)行最內(nèi)層或最外層的事件,根據(jù)內(nèi)外層關(guān)系來把范圍更廣的事件取消掉(對于新手來說,不取消冒泡,很容易中招的出現(xiàn) bug)。event.stopPropagation()(IE 中window.event.cancelBubble = true)可以用來取消事件冒泡。

有時候?qū)τ跒g覽器的默認(rèn)事件也需要取消,這時候用到的函數(shù)則是 event.preventDefault()(IE 中window.event.returnValue = false)。

那么默認(rèn)事件取消和停止冒泡有什么區(qū)別呢?我的理解:瀏覽器的默認(rèn)事件是指瀏覽器自己的事件(這不廢話嗎),比如 a 標(biāo)簽 的點擊,表單的提交等,取消掉就不會執(zhí)行啦;冒泡則取消的是由外向里(捕獲)、由里向外(冒泡),stop 之后,就不會繼續(xù)遍歷了。stackoverflow 上的解答

看下例子,依舊是上面那個例子,不過每個函數(shù)都加了 停止冒泡:

s1.addEventListener("click",function(e){
  e.stopPropagation();
  alert("s1");
},false);
s2.addEventListener("click",function(e){
  e.stopPropagation();
  alert("s2");
},true);
s3.addEventListener("click",function(e){
  e.stopPropagation();
  alert("s3");
},false);

點擊的結(jié)果是:當(dāng)點擊 s2 或 s3 的時候,都會 alert s2,點擊 s1,彈出 s1。因為事件被取消的緣故,點擊 s3,執(zhí)行 s2后就不會在向下執(zhí)行了。

在看一個 preventDefault 的例子。



第二個鏈接是不是回不了主頁,因為瀏覽器的默認(rèn)事件被取消了。

以上所有例子請在非低版本 IE 瀏覽器的環(huán)境下瀏覽 O_o

總結(jié)

總結(jié)就補充兩個兼容 IE 的函數(shù)吧:

function stopBubble(e) {
  //如果提供了事件對象,則這是一個非IE瀏覽器
  if ( e && e.stopPropagation )
      //因此它支持W3C的stopPropagation()方法
      e.stopPropagation();
  else
      //否則,我們需要使用IE的方式來取消事件冒泡
      window.event.cancelBubble = true;
}
//阻止瀏覽器的默認(rèn)行為
function stopDefault( e ) {
  //阻止默認(rèn)瀏覽器動作(W3C)
  if ( e && e.preventDefault )
      e.preventDefault();
  //IE中阻止函數(shù)器默認(rèn)動作的方式
  else
      window.event.returnValue = false;
  return false;
}

共勉!

參考

stackoverflow 什么是事件冒泡和捕捉
stackoverflow stopPropagation 和 preventDefault 的區(qū)別
MDN addEventListener
javascript阻止事件冒泡和瀏覽器的默認(rèn)行為

由于 SF 編輯器不支持上傳 demo,只能以圖片展示,歡迎來 我的博客 查看 demo。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80689.html

相關(guān)文章

  • JS事件冒泡捕獲

    摘要:事件冒泡與事件捕獲事件冒泡和事件捕獲分別由微軟和網(wǎng)景公司提出,這兩個概念都是為了解決頁面中事件流事件發(fā)生順序的問題。事件冒泡微軟提出了名為事件冒泡的事件流。 事件冒泡與事件捕獲 事件冒泡和事件捕獲分別由微軟和網(wǎng)景公司提出,這兩個概念都是為了解決頁面中事件流(事件發(fā)生順序)的問題??紤]下面這段代碼,就不寫html->head,body之類的代碼了,自行腦補 Click me! ...

    sixleaves 評論0 收藏0
  • JS中的事件順序(事件捕獲冒泡)

    摘要:問題如果一個元素和它的祖先元素注冊了同一類型的事件函數(shù)例如點擊等那么當(dāng)事件發(fā)生時事件函數(shù)調(diào)用的順序是什么呢比如考慮如下嵌套的元素 問題 如果一個元素和它的祖先元素注冊了同一類型的事件函數(shù)(例如點擊等), 那么當(dāng)事件發(fā)生時事件函數(shù)調(diào)用的順序是什么呢? 比如, 考慮如下嵌套的元素: ----------------------------------- | outer ...

    張遷 評論0 收藏0
  • JS中的事件順序(事件捕獲冒泡)

    摘要:問題如果一個元素和它的祖先元素注冊了同一類型的事件函數(shù)例如點擊等那么當(dāng)事件發(fā)生時事件函數(shù)調(diào)用的順序是什么呢比如考慮如下嵌套的元素 問題 如果一個元素和它的祖先元素注冊了同一類型的事件函數(shù)(例如點擊等), 那么當(dāng)事件發(fā)生時事件函數(shù)調(diào)用的順序是什么呢? 比如, 考慮如下嵌套的元素: ----------------------------------- | outer ...

    ixlei 評論0 收藏0
  • javascript -- 事件--事件流-- 冒泡 --捕獲

    摘要:在內(nèi)聯(lián)模型中,事件處理函數(shù)是標(biāo)簽的一個屬性,用于處理指定事件。事件捕獲與冒泡原理圖事件流同時支持兩種事件模型捕獲型事件和冒泡型事件,但是,捕獲型事件先發(fā)生。 javascript -- 事件 事件是js和用戶操作交互的橋梁, JavaScript 有三種事件模型:內(nèi)聯(lián)模型、腳本模型和 DOM2 模型 內(nèi)聯(lián)模型 這種模型是最傳統(tǒng)接單的一種處理事件的方法。在內(nèi)聯(lián)模型中,事件處理函數(shù)是 HT...

    leeon 評論0 收藏0
  • JS復(fù)習(xí)-JS事件捕獲冒泡

    摘要:也就是說事件流一定是按上面的順序經(jīng)過這三個階段。關(guān)于事件捕獲,事件冒泡的引用場景,有事件委托等。下面引用兩篇文章。 什么是捕獲?什么是冒泡? 給元素綁定事件會經(jīng)歷三個階段:一:捕獲階段(capture phase)--先從根元素流向目標(biāo)元素;二:目標(biāo)階段(target phase)--在目標(biāo)元素上的事件被觸發(fā);三:冒泡階段(bubbling phase)--目標(biāo)元素流向根元素 就像你中...

    BakerJ 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<