天天看點

Javascript——冒泡與捕獲

什麼是冒泡與捕獲

        以click點選事件為例。假如我們有一個多層結構标簽。如下圖,是4個div嵌套。每個div都有點選的監聽事件,分别輸出1234。當我們點選最裡面的div時,點選事件開始傳遞,傳遞的全過程是1-2-3-4-4-3-2-1。

前半部分,事件從最外面的父div依次傳遞到最裡面的後代div,1-2-3-4這部分我們叫捕獲過程。

之後事件又從最裡層的後代div逐層傳出,4-3-2-1這部分我們叫冒泡過程。

如果我把捕獲監聽器和冒泡監聽器都加上,如下圖這樣。

Javascript——冒泡與捕獲

                                                                                 事件傳遞

這時我們有8個監聽器了,在捕獲過程和冒泡過程都有監聽。輸出如下圖。

Javascript——冒泡與捕獲

                                                                                     先捕獲後冒泡

如果我去除幾個監聽器如下圖。為了容易了解我調整了格式

Javascript——冒泡與捕獲

                                                                                           舉一反三

仍然是按照箭頭順序,明顯應該輸出1423。

Javascript——冒泡與捕獲

                                                                                            舉一反三

添加兩種監聽的方法

        在不使用任何架構的情況下,我們在js中通過addEventListener方法給Dom添加事件監聽。這個方法有三個參數可以傳遞addEventListener(event,fn,useCapture)。event是事件類型click,focus,blur等;fn是事件觸發時将執行的函數方法(function);第三個參數可以不傳,預設是false,這個參數控制是否捕獲觸發。是以我們隻穿兩個參數時,這個事件是冒泡傳遞觸發的,當第三個參數存在且為true時,事件是捕獲傳遞觸發的。

        使用架構時可使用對應的架構提供的方法。如上面我使用了Vue架構,通過事件裝飾來區分捕獲與冒泡。

阻止傳遞

        在不使用任何架構的情況下,我們在js中通過stopPropagation方法阻止事件繼續傳遞。

        使用架構時可使用對應的架構提供的方法。接下來我将了Vue架構的stop修飾符來阻止事件傳遞。

        我們可以在傳遞過程中阻止事件繼續傳遞,防止觸發不需要的事件。

Javascript——冒泡與捕獲

                                                                                        阻止傳遞

如圖我在第三層捕獲後阻止事件繼續傳遞,那麼後面的log方法不會繼續執行。最終隻輸出1-2-3。

Javascript——冒泡與捕獲

                                                                                        輸出結果

應用場景舉例

        我們在使用中多數情況下隻使用冒泡監聽。例如一條購物車資訊,在這條資訊中,右下角有一個删除按鈕。點選這條消息可檢視詳情,點選删除按鈕可将此商品移除。我們會分别給資訊的div和删除button添加一個冒泡的click事件監聽。如果不做阻止傳遞,點選删除button後,會顯示商品詳情。顯然這不是我們想看到的。這時我們給button一個阻止事件傳遞的功能,點選删除按鈕後,事件就會結束,就不再顯示商品詳情。

js