javascript事件冒泡和事件捕獲及事件代理

一:什麼是事件?

事件是文檔和瀏覽器窗口中發生的特定的交互瞬間。 事件是javascript應用 跳動的心臟,也是把所有東西黏在一起的膠水,當我們與瀏覽器中web頁面進 行某些類型的交互時,事件就發生了。 事件可能是用戶在某些內容上的點擊,鼠標經過某個特定元素或按下鍵盤 上的某些按鍵,事件還可能是web瀏覽器中發生的事情,比如說某個web頁面 加載完成,或者是用戶滾動窗口或改變窗口大小。

二:什麼是事件流?

事件流描述的是從頁面中接受事件的順序,但有意思的是,微軟(IE)和網 景(Netscape)開發團隊居然提出了兩個截然相反的事件流概念,IE的事件流是 事件冒泡流(eventbubbling),而Netscape的事件流是事件捕獲流(eventc apturing)。

三:事件冒泡和事件捕獲的概念:

事件冒泡和事件捕獲是描述事件觸發事件時序問題的術語,事件捕獲指的是 從document到觸發事件的那個節點,也就是說自上而下的去觸發事件,相反的, 事件冒泡是自下而上的去觸發事件,綁定事件方法的第三個參數,就是控制事件 觸發順序是否爲事件捕獲,true爲事件捕獲,false爲事件冒泡,jQuery的 e.stopPropagation會阻止冒泡,意思就是到我爲止,我的爹和祖宗的事件就不要 觸發了。

3.1 第一種:事件冒泡

IE提出的事件流叫做事件冒泡,即事件開始時由最具體的元素接收,然後逐級向上傳播到較爲不具體的節點
執行順序:p=>button=>div=>body 正如上面我們所說的,它會從一個最具體的的元素接收,然後逐級向上傳播,p =>button=>div=>body…事件冒泡可以形象地比喻爲把一顆石頭投入水中,泡 泡會一直從水底冒出水面,也就是說從小到大開始傳播。
代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div class="box" >
    1
    <div class="box2">
      22

        <div class="box3">
            33
          </div>
    </div>
  </div>
  
  
  
</body>
<script>
  var box1=document.querySelector('.box');
  var box2=document.querySelector('.box2');
  var box3=document.querySelector('.box3');
box3.addEventListener('click',fun1,false);
function fun1 (){
  console.log('事件3')

}
box2.addEventListener('click',fun2,false);
function fun2 (){
  console.log('事件2')

}
box1.addEventListener('click',fun3,false);
function fun3 (){
  console.log('事件1')

}

</script>
</html>
//我們給最裏面的那個盒子添加事件的話會觸發前邊兩個 這就是所謂的冒泡 
//在js中冒泡我們用的是 stopproganation
//vue是.stop
3.2 第二種:事件捕獲

網景公司提出的事件流叫事件捕獲流。 事件捕獲流的思想是不太具體的DOM節點應該更早接收到事件,而最具體的 節點應該最後接收到事件,針對上面同樣的例子,點擊按鈕,那麼此時click事 件會按照這樣傳播:(下面我們就借用addEventListener的第三個參數來模擬事 件捕獲流),也就是上面的例子就會倒過來。
正如我們看到的,和冒泡流萬全相反,從最不具體的元素接收到最具體的元 素接收事件 body=>div=>button=>p
代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div class="box" >
    1
    <div class="box2">
      22

        <div class="box3">
            33
          </div>
    </div>
  </div>
  
  
  
</body>
<script>
  var box1=document.querySelector('.box');
  var box2=document.querySelector('.box2');
  var box3=document.querySelector('.box3');
box3.addEventListener('click',fun1,true);
function fun1 (){
  console.log('事件3')

}
box2.addEventListener('click',fun2,true);
function fun2 (){
  console.log('事件2')

}
box1.addEventListener('click',fun3,true);
function fun3 (){
  console.log('事件1')

}




</script>
</html>
//只需要改成 true就可以 從父級往下觸發 一次獲取

阻止冒泡捕獲的是

  e.stopPropagation()
原生的默認捕獲事件是preventdefult
vue阻止默認行爲是   .prevent
事件代理

js原生中事件代理 在父級元素上綁定處理函數,通過e.target來獲取觸發的目標來做。
jQuery呢我們通過 給父級元素綁定事件,不給自己元素綁定事件,然後再當點擊子元素的時候,通過冒泡機制來觸發父組件的處理函數
主要目的還是爲了能夠提高性能,這樣的話我們就不需要給每個族元素綁定時間了,只需要給父元素綁定。
代碼如下:

//js原生實現
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>

  <ul >
    <li>11</li>
    <li>22</li>
    <li>33</li>
  </ul>
  
  
</body>
<script>
 var ul=document.querySelector('ul');
 ul.onclick=function(e){
   var target=e.target
   if(e.target.nodeName=="li"){
     alert('111')
   }
 }




</script>
</html>
//jQuery實現:
  //第一個是我們綁定的 事件 第二個是 處罰的具體目標 第三個是 事件的邏輯處理
$('ul').on('click','li',function(){
  //事件邏輯
})

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章