日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

聊聊事件冒泡與事件捕獲

 印度阿三17 2019-04-05

什么是事件?

?  事件是文檔和瀏覽器窗口中發(fā)生的特定的交互瞬間。

什么是事件流:

? ?事件流描述的是從頁面中接受事件的順序( 說白了就是解決頁面中事件流發(fā)生順序的問題。),但有意思的是,微軟(IE)和網(wǎng)景(Netscape)開發(fā)團隊居然提出了兩個截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕獲流(event capturing)。

?

讓我們先聊聊DOM0級事件與DOM2級事件

?

  • DOM0

直接通過 onclick寫在html里面的事件, 比如:

在標簽內(nèi)寫onclick事件

<input onclick="alert(1)" />

?在JS寫onlicke=function(){}函數(shù)

1 document.getElementById("myButton").onclick = function () {
2     alert('thanks');
3 }

?

?

  • DOM2

主流瀏覽器DOM2級事件是通過以下兩個方法用于處理指定和刪除事件處理程序的操作:

  1. 添加事件 ??addEvenetListener ? ?------ ? 可以為元素添加多個事件處理程序,觸發(fā)時會按照添加順序依次調(diào)用。
  2. 刪除事件 ??removeEventListener ? ------- ??不能移除匿名添加的函數(shù)。

它們都有三個參數(shù):

  1. 第一個參數(shù)是事件名(如click)。
  2. 第二個參數(shù)是事件處理程序函數(shù)。 ?可以為匿名函數(shù),也可以為命名函數(shù)(但如果需要刪除事件,必須是命名函數(shù))
  3. 第三個參數(shù)如果是true則表示在捕獲階段調(diào)用,為false表示在冒泡階段調(diào)用。

使用DOM 2級事件處理程序的主要好處是可以添加多個事件處理程序,事件處理會按照他們的順序觸發(fā),通過addEventListener添加的事件只能用removeEventListener來移除,移除時傳入的參數(shù)與添加時使用的參數(shù)必須相同,這也意味著添加的匿名函數(shù)將無法移除,(注意:我們默認的第三個參數(shù)都是默認false,是指在冒泡階段添加,大多數(shù)情況下,都是將事件處理程序添加到事件的冒泡階段,這樣可以最大限度的兼容各個瀏覽器

?

匿名函數(shù)

1 //這是一個DOM 2級事件 添加事件最簡單的方式(此時添加的是一個匿名函數(shù))
2     <button>按鈕</button>
3     <script>
4         var btn=document.querySelector('button');
5         btn.addEventListener('click',function(){
6             console.log('我是按鈕')
7         },false)   //當?shù)谌齻€參數(shù)不寫時,也是默認為false(冒泡時添加事件)
8     </script>

?

命名函數(shù)

1     <button>按鈕</button>
2     <script>
3         var btn=document.querySelector('button');
4         btn.addEventListener('click',foo,false);
5         function foo(){
6             console.log('我是按鈕')
7         }
8            //其實操作就是把寫在里面的函數(shù)拿到了外面,而在原來的位置用函數(shù)名來代替
9     </script>

?


?

看完以上的,我們再了解事件冒泡與捕獲

?


?

第一種(事件冒泡)IE提出

IE提出的事件流叫做事件冒泡,即事件開始時由最具體的元素接收,然后逐級向上傳播到較為不具體的節(jié)點。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body onclick="bodyClick()">
 8 
 9     <div onclick="divClick()">
10         <button onclick="btn()">
11             <p onclick="p()">點擊冒泡</p>
12         </button>
13     </div>
14     <script>
15        
16        function p(){
17           console.log('p標簽被點擊')
18        }
19         function btn(){
20             console.log("button被點擊")
21         }
22          function divClick(event){
23              console.log('div被點擊');
24          }
25         function bodyClick(){
26             console.log('body被點擊')
27         }
28 
29     </script>
30 
31 </body>
32 </html>

接下來我們點擊一下頁面上的p元素,如下所示

正如上面我們所說的,它會從一個最具體的的元素接收,然后逐級向上傳播, p=>button=>div=>body..........事件冒泡可以形象地比喻為把一顆石頭投入水中,泡泡會一直從水底冒出水面。

??


??

第二種(事件捕獲)網(wǎng)景提出

事件捕獲流的思想是不太具體的DOM節(jié)點應該更早接收到事件,而最具體的節(jié)點應該最后接收到事件,針對上面同樣的例子,點擊按鈕,那么此時click事件會按照這樣傳播:(下面我們就借用addEventListener的第三個參數(shù)來模擬事件捕獲流)

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <div>
10     <button>
11         <p>點擊捕獲</p>
12     </button>
13 </div>
14 <script>
15     var oP=document.querySelector('p');
16     var oB=document.querySelector('button');
17     var oD=document.querySelector('div');
18     var oBody=document.querySelector('body');
19 
20     oP.addEventListener('click',function(){
21         console.log('p標簽被點擊')
22     },true);
23 
24     oB.addEventListener('click',function(){
25         console.log("button被點擊")
26     },true);
27 
28     oD.addEventListener('click',  function(){
29         console.log('div被點擊')
30     },true);
31 
32     oBody.addEventListener('click',function(){
33         console.log('body被點擊')
34     },true);
35 
36 </script>
37 </body>
38 </html>

同樣我們看一下后臺的打印結(jié)果

和冒泡流完全相反,從最不具體的元素接收到最具體的元素接收事件? body=>div=>button=>p?

?


?

  • 事件代理

在實際的開發(fā)當中,利用事件流的特性,我們可以使用一種叫做事件代理的方法。

<ul id="color-list">
    <li>red</li>
    <li>yellow</li>
    <li>blue</li>
    <li>green</li>
    <li>black</li>
    <li>white</li>
</ul>

?

?如果點擊頁面中的li元素,然后輸出li當中的顏色,我們通常會這樣寫:

1 var list_li = document.getElementsByTagName('li');
2 for (var i = 0; i < list_li.length; i  ) {
3     list_li[i].addEventListener('click',foo,false);
4 }
5 function foo (e) {
6    let x = e.target;
7    console.log(x.innerHTML)
8 }

?

利用事件流的特性,我們只綁定一個事件處理函數(shù)也可以完成:

1 var list_ul = document.getElementById('color-list');
2 list_ul.addEventListener('click', foo, false);
3 function foo (e) {
4     let x = e.target;
5     if (x.nodeName == 'LI') {
6       console.log(x.innerHTML)
7     }
8 }

?

?


?

  • 冒泡還是捕獲?

    對于事件代理來說,在事件捕獲或者事件冒泡階段處理并沒有明顯的優(yōu)劣之分,但是由于事件冒泡的事件流模型被所有主流的瀏覽器兼容,從兼容性角度來說還是建議大家使用事件冒泡模型。

?

  IE瀏覽器兼容

   IE瀏覽器對addEventListener兼容性并不算太好,只有IE9以上可以使用。

   要兼容舊版本的IE瀏覽器,可以使用IE的attachEvent函數(shù)

object.attachEvent(event, function)

   兩個參數(shù)與addEventListener相似,分別是事件和處理函數(shù),默認是事件冒泡階段調(diào)用處理函數(shù)。并且由于IE瀏覽器只支持事件冒泡,所以添加的程序都被添加到冒泡階段。要注意的是,寫事件名時候要加上"on"前綴("onload"、"onclick"等)。

?

 區(qū)別

  addEventListener與attachEvent除了參數(shù)個數(shù)以及第一個參數(shù)意義不同外。還有如下兩點:

  1. 事件處理程序的作用域不相同:addEventListener的作用域是元素本身,this指的是觸發(fā)元素。而attachEvent事件處理程序會在全局變量內(nèi)運行,this指的是window,所以剛才的例子返回的結(jié)果是undefined,而不是元素id。
  2. 為一個事件添加多個事件處理程序時,執(zhí)行順序不同:使用addEventListener時瀏覽器會按照添加順序執(zhí)行,IE瀏覽器使用attachEvent時,如果添加的方法過多時,IE瀏覽器將不會按照順序執(zhí)行。

?


?

  • 阻止事件冒泡與阻止默認事件

  阻止事件冒泡 ??stopPropagation() 方法

  可以阻止事件冒泡,也可以阻止事件捕獲,也可以阻止處于目標階段

  使用stopPaopagation()方法可以停止事件在DOM層次的傳播,不再派發(fā)事件。

 1 <div id="p">parent
 2       <div id="c">child</div>
 3 </div>
 4 <script type="text/javascript">
 5 var p = document.getElementById('p'),
 6       c = document.getElementById('c');
 7       c.addEventListener('click', function (e) {
 8       e.stopPropagation()
 9            alert('子節(jié)點冒泡')   //不再向上冒泡到父級
10 }, false);
11 p.addEventListener('click', function () {
12          alert('父節(jié)點冒泡')}, false);
13 </script>

?

  阻止默認事件 ??event.preventDefault() 方法 ? (基本沒作用吧...很少有需求將默認事件取消掉吧)

event.preventDefault()

?

?

來源:http://www./content-4-156851.html

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多