關於JS事件捕獲與事件冒泡機制的理解


  最近參考了網上很多關於JS事件捕獲和事件冒泡機制的文章,以下內容為個人對之理解,方便日后查閱。

  事件捕獲和事件冒泡是啥?

  事件捕獲和事件冒泡分別是Netscape和IE對DOM事件產生順序的描述。Netscape認為DOM接收的事件最先應該是window接收,然后再一節一節往下,最后才是具體的元素接收到事件,即:事件捕獲。而IE則認為DOM事件應該由具體元素最先接收事件,然后再一節一節往上,最后再由window接收事件,即:事件冒泡。最后W3C將兩種方案做了統一,即:把DOM事件分為兩個階段,事件捕獲階段和事件冒泡階段,例如:當頁面某一個元素被點擊,首先是事件捕獲階段,window最先接收事件,然后一節一節往下捕獲,最后由具體元素接收,然后再由具體元素一節一節往上,最后window會再次接收事件,以下為DOM事件流示意圖:

 

這樣當頁面上一個對象觸發某個事件,我們會有兩次機會對其進行操作!雖然DOM2級事件規范中要求事件捕獲過程中不會涉及事件目標,但是各高版本瀏覽器中都會在事件捕獲過程中觸發對象事件。

 

  在JS事件學習中常常會看到或者聽到事件代理(事件委托)這個說法,那么,什么是事件代理(事件委托)?

  什么是事件代理(事件委托)?

  看上去很抽象,可以用一個例子來簡單說明其原理:我們在網上購物,我們會留下一個具體地址來接收包裹,但是由於快遞員不能每一件都親自送到我們手中,所以,快遞代收站出現了,快遞員只需要把快遞放在快遞站,然后再繼續派送其他快遞,我們只需要在適當的時機到快遞站取快遞即可。在這個過程中,包裹就是某個事件,快遞員派送的過程就是時間捕獲的過程,適當的時機即事件捕獲到來最底層的具體得到元素,我們去快遞站取快遞就是時間冒泡的過程,所以事件代理(事件委托)就是利用事件冒泡原理在快遞站(父元素)接收我們的快遞(事件),然后我們再去快遞站取款地(事件冒泡)。js中提供了event對象,在這個對象中有個target屬性,通過target屬性我們就能知道具體是哪個元素觸發了事件。

  為什么是要使用事件代理(事件委托)?

  為什么會有快遞站呢?當然是提高效率,如果快遞員每一件播過都親自送到用戶手中,那效率得多低。事件代理也如此,我們操作DOM的是代價的,應該盡量避免頻繁的操作DOM元素,如果我們給DOM每一個元素都添加事件,理論上沒有任何問題,但是從效率,優化上來講顯得過於麻煩低效。

 

事件代理簡單DEMO:

   <style> 
 2         li {
 3             width: 100px;
 4             height: 50px;
 5             background-color: pink;
 6         }
 7         div {
 8             width: 80%;
 9             height: 80%;
10             background-color: red;
11         }
12         span {
13             display: block;
14             width: 80%;
15             height: 80%;
16             background-color: cyan;
17 
18         }
19         a {
20             display: block;
21             width: 80%;
22             height: 80%;
23             background-color: greenyellow;
24         }
25     </style>
26 </head>
27 <body>
28     <ul>
29         <li>
30             <div>
31                 <span>
32                     <a href="javascript:;">A</a>
33                 </span>
34             </div>
35         </li>
36         <li>2</li>
37         <li>3</li>
38         <li>4</li>
39         <li>5</li>
40         <li>6</li>
41     </ul>
42 <script>
43     var ul = document.querySelector('ul');
44     ul.addEventListener('click', function (e) { 
45         console.log(e.target);
46         
47      });
48 </script>

以上代碼只對ul進行了事件監聽,但是當我們分別點擊不同元素時,即使該元素沒有添加事件監聽,同樣會在控制台上顯示我們點擊了這個元素,這就是事件代理(事件委托)。

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM