事件冒泡 事件捕獲和事件委託

2022-08-17 02:24:15 字數 3288 閱讀 8541

事件冒泡會從當前觸發的事件目標一級一級往上傳遞,依次觸發,直到document為止。

事件捕獲會從document開始觸發,一級一級往下傳遞,依次觸發,直到真正事件目標為止。

事件委託依靠的就是事件冒泡和事件捕獲的機制。

"

box1

">

"box2

">

"box3

">

上面是三個具有父子關係的box,分別繫結了列印事件,現在點選最中間的紅色box

可以看到,當為事件冒泡時,會從觸發事件的元素一直往外冒泡直到document為止

將false改成true,還是點選最中間的紅色div

可以看到,當為事件捕獲時,從document根文件到當前元素觸發事件

舉個栗子來了解事件委託:

有三個同事預計會在周一收到快遞,為了簽收快遞,有兩種辦法:1.三個人在公司門口等快遞;2.委託給前台mm代為簽收。現實當中,我們大都採用委託的方案(公司也不會容忍那麼多員工站在門口就為了等快遞)。前台mm收到快遞後,她會判斷收件人是誰,然後按照收件人的要求簽收,甚至代為付款。這種方案還有乙個優勢,那就是即使公司裡來了新員工(不管多少),前台mm也會在收到寄給新員工的快遞後核實並代為簽收(可以給暫時不存在的節點也繫結上事件)。

應用場景:

現在有乙個ul,ul裡又有100個li,我想給這100個li都繫結乙個點選事件,我們一般可以通過for迴圈來繫結,但是要是有1000個li呢? 為了提高效率和速度,所以我們這時可以採用事件委託,只給ul繫結乙個事件,根據事件冒泡的規則,只要你點了ul裡的每乙個li,都會觸發ul的繫結事件,我們在ul繫結事件的函式裡通過一些判斷,就可以給這100li都觸發點選事件了。

具體**:

function clickli() 

document.getelementbyid(

'isul

').addeventlistener('

click

', function (event

) });

這樣我們就通過給ul繫結乙個點選事件,讓所有的li都觸發了函式。

那如果想給不同的li繫結不同的函式怎麼辦?

假設有3個li,我們先寫3個不同的函式,再給3個li設定不同的id名,通過判斷id名是不是就能給不同的li繫結不同的函式啦:

這就是所謂的事件委託,通過監聽乙個父元素,來給不同的子元素繫結事件,減少監聽次數,從而提公升速度。

(1).提高效能:每乙個函式都會占用記憶體空間,只需新增乙個時間處理程式**所有事件,所占用的記憶體空間更少;

(2).動態監聽:使用事件委託可以自動繫結動態新增的元素,即新增的節點不需要主動新增也可以具有和其它元素一樣的事件。

那麼,能不能阻止元素的事件冒泡呢,答案是可以的。

一開始那個例子,假如我們真的只想點選最裡面的那個紅色box,不想另外兩個box的事件被觸發,我們可以在給紅色box繫結事件的函式裡這麼寫

這樣我們再點選紅色的box,那就只會觸發它本身的事件啦。

看這個應用場景:

這是乙個模態框,現在的需求是當我們點選紅色的按鈕需要跳轉頁面,然後點選白色的對話方塊不需要任何反應點其它任何地方就關閉這個模態框

這裡就需要用到阻止冒泡了,紅色的按鈕是白色對話方塊的子元素,白色對話方塊又是這整個模態框的子元素,我們給模態框加上乙個點選事件關閉,然後給紅色的按鈕加上乙個點選事件跳轉,這時就產生了乙個問題,只要點選白色的對話方塊,由於冒泡機制,這個模態框也會關閉,實際上我們並不想點選白色的對話方塊有任何反應,這時我們就給這個白色的對話方塊繫結乙個點選事件,函式裡寫上event.stoppropagation();,這樣就ok了。

老版本的ie存在相容問題,根本不支援addeventlistener()的新增事件和removeeventlistener()的刪除事件,它有自己的監聽方法:

//

新增事件,事件流固定為冒泡

attachevent(事件名,事件處理函式)

//刪除事件

detachevent(事件名,事件處理函式)

還有ie裡的事件物件是window.event,事件源是srcelement,阻止冒泡寫法也不一樣:

function() 

function(

event

)

關於js的瀏覽器相容問題,一般用能力檢測來解決,if(){}else{}

我們平時工作一般都是用jquery,ie這些特殊情況早就幫我們做好相容啦。

jquery在1.7的版本之後,最流行的事件監聽方法是$(元素).on(事件名,執行函式),它還有一種事件委託的寫法$(委託給哪個元素).on(事件名,被委託的元素,執行函式)

JS事件冒泡 事件捕獲和事件委託

如上圖所示 事件冒泡 結構上從內到外 如上圖所示 事件捕獲 結構上從外到內 使用addeventlistener 方法指定事件是否在捕獲或冒泡階段執行 element.addeventlistener event,function,usecapture usecapture 可選。布林值,指定事件是...

事件冒泡與捕獲 事件委託

設想這樣一種情況 乙個div裡面有個span元素 當滑鼠單擊span時,這個事件算是誰的?div還是span?準確的說兩個都觸發了,這種認可大家都同意,事實就是這樣的,第二個問題來了,這個事件應該有個先後順序 先觸發span還是div?早期就有兩個主流的瀏覽器廠商各執己見,ie認為,這個事件首先觸發...

事件冒泡和事件捕獲

事件冒泡 事件物件沿dom樹向上傳播 事件捕獲 事件物件沿dom樹向下傳播 addeventlistener click function flase 引數預設為false 代表事件冒泡,引數為true代表事件捕獲 attachevent onclick function detachevent 沒...