淺析jQuery中的事件冒泡

什么是事件冒泡


在一個對象上觸發(fā)某類事件,如果此對象定義了此事件的處理程序,那么此事件就會調(diào)用這個處理程序,如果沒有定義此事件處理程序或者事件返回true,那么這個事件會向這個對象的父級對象傳播,從里到外,直至它被處理,或者它到達了對象層次的最頂層,即document或window對象。在一個頁面上可以有多個事件,也可以有多個元素響應同一個事件,如:網(wǎng)頁上有兩個元素,其中一個元素嵌套在另一個元素里,并且都被綁定了 click 事件,同時 <body> 元素也綁定了 click 事件,當執(zhí)行一次 click 事件時,將會觸發(fā)三次響應,代碼如下:

<div id="box">
  外層div
  <br>
  <br>
  <br>
  <span>內(nèi)層span</span>
  <br>
  <br>
  <br>
  外層div
</div>
<div id="msg"></div>
<script>
  $(function(){
    //為span元素綁定click事件
    $("span").on("click",function(){
      var txt = $("#msg").html() + "<p>內(nèi)層span被點擊</p>";
      $("#msg").html(txt);
    });
    //為div元素綁定事件
    $("#box").on("click",function(){
      var txt = $("#msg").html() + "<p>外層div被點擊</p>";
      $("#msg").html(txt);
    });
    //為body元素綁定事件
    $("body").on("click",function(){
      var txt = $("#msg").html() + "<p>body被點擊</p>";
      $("#msg").html(txt);
    });
  })
</script>

頁面效果如圖:

頁面效果圖

當單擊內(nèi)部<span>元素,即觸發(fā)<span>元素的click事件,會輸出3條記錄,如圖:
單擊span元素

只單擊內(nèi)部<span>就會觸發(fā)外部<div>和<body>元素上綁定的click事件,這就是由事件冒泡所引起的。
只單擊<span>元素的同時,也單擊了包含<span>元素的元素<div>和包含<div>元素的元素元素<body>,并且每一個元素都會按照特定的順序響應click事件。

元素的click事件會按照以下順序“冒泡”:

  1. <span>
  2. <div>
  3. <body>

之所以稱為冒泡,是因為事件會按照DOM的層次結(jié)構(gòu)像水泡一樣不斷向上直至頂端,此列即為從<span>到<body>。

如何阻止事件冒泡


事件冒泡帶來的問題

事件冒泡處理可能會激活我們本來不想激活的事件,導致程序錯亂,甚至無從下手調(diào)試,這常成為對事件冒泡不熟悉程序員的棘手問題。如上例中,本只想觸發(fā)<span>元素的click事件,然而<div>和<body>元素的click事件也同時被觸發(fā)。因此,有必要對事件的作用范圍進行限制。

  • 事件對象
    由于IE-DOM和標準DOM實現(xiàn)事件對象的方法各不相同,導致在不同瀏覽器中獲取事件對象變得比較困難。針對這個問題,jQuery進行了必要的擴展和封裝,從而使得在任何瀏覽器中能很輕松地獲取事件對象以及事件對象的一些屬性。如下,為函數(shù)添加一個函數(shù)便可使用事件對象:
$("#element").on("click",function(event){  //event : 事件對象
  //...
})

這樣,當單擊“element”元素時,事件對象就被創(chuàng)建了。這個事件對象只有事件處理函數(shù)才能訪問到,事件處理函數(shù)執(zhí)行完畢后,事件對象也就被銷毀了。

  • 阻止事件冒泡
    停止事件冒泡可以阻止事件中對其他對象的事件處理函數(shù)被執(zhí)行。在jQuery中提供了 stopPropagation() 方法來停止事件冒泡。上例中代碼可修改如下:
$("span").on("click",function(event){  //event : 事件對象
      var txt = $("#msg").html() + "<p>內(nèi)層span被點擊</p>";
      $("#msg").html(txt);
      event.stopPropagation();  //停止事件冒泡
    });

這樣,當單擊<span>元素時,只會觸發(fā)該元素上的click事件。使用 stopPropagation() 方法同樣可以阻止<div>上的事件冒泡問題。

  • 阻止默認行為
    網(wǎng)頁中的元素有自己的默認行為,如點擊超鏈接會跳轉(zhuǎn),“提交”按鈕會提交表單,有事需要對這種默認行為進行阻止。
    在jQuery中,提供了 preventDefault() 方法來阻止元素的默認行為。

看到這,你一定以為如果想同時對事件對象停止冒泡和默認行為,同時調(diào)用 stopPropagation()  和 preventDefault() 方法就可以了,當然,這種方法也沒問題,但有一種簡寫方式:在事件處理函數(shù)中返回 false 即可。

      event.stopPropagation();  //停止事件冒泡

改寫為

      return false;

事件捕獲


事件捕獲其實就是事件冒泡的相反過程,事件捕獲是從最頂端往下開始觸發(fā)。事件捕獲是石子從水面落入水底,而事件冒泡是從水底打撈石子到水面。
遺憾的事,并非所有主流瀏覽器都支持事件捕獲,并且jQuery不支持事件捕獲,如果需要使用事件捕獲,請直接使用原生JavaScript,本文不再解釋。


學藝不精,難免有錯誤之處,如您發(fā)現(xiàn)有不能忍受的錯誤,請聯(lián)系本人,將萬分感激

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 總結(jié): 鼠標事件 1.click與dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r閱讀 1,721評論 2 10
  • JavaScript 程序采用了異步事件驅(qū)動編程模型。在這種程序設計風格下,當文檔、瀏覽器、元素或與之相關的對象發(fā)...
    劼哥stone閱讀 1,333評論 3 11
  • 以下文章為轉(zhuǎn)載,對理解JavaScript中的事件處理機制很有幫助,淺顯易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy閱讀 3,169評論 1 10
  • js之事件機制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驅(qū)動...
    道無虛閱讀 2,632評論 0 2
  • 這輩子有你,剛好 因為 我已經(jīng)不知道前生是否曾相約 在喝過孟婆湯、踏過奈何橋 這輩子有你,剛好 因為 我不知道來世...
    王宇翔閱讀 890評論 0 5

友情鏈接更多精彩內(nèi)容