JavaScript 詳說事件機制之冒泡、捕獲、傳播、委托

DOM事件流(event? flow?)存在三個階段:事件捕獲階段、處于目標階段、事件冒泡階段。

事件捕獲event? capturing通俗的理解就是,當鼠標點擊或者觸發dom事件時,瀏覽器會從根節點開始由外到內進行事件傳播,即點擊了子元素,如果父元素通過事件捕獲方式注冊了對應的事件的話,會先觸發父元素綁定的事件。

事件冒泡dubbed? bubbling與事件捕獲恰恰相反,事件冒泡順序是由內到外進行事件傳播,直到根節點。

無論是事件捕獲還是事件冒泡,它們都有一個共同的行為,就是事件傳播,它就像一跟引線,只有通過引線才能將綁在引線上的鞭炮(事件監聽器)引爆,試想一下,如果引線不導火了,那鞭炮就只有一響了!!!

  

  dom標準事件流的觸發的先后順序為:先捕獲再冒泡,即當觸發dom事件時,會先進行事件捕獲,捕獲到事件源之后通過事件傳播進行事件冒泡。不同的瀏覽器對此有著不同的實現,IE10及以下不支持捕獲型事件,所以就少了一個事件捕獲階段,IE11、Chrome?、Firefox、Safari等瀏覽器則同時存在。

說到事件冒泡與捕獲就不得不提一下兩個用于事件綁定的方法addEventListener、attachEvent。當然還有其它的事件綁定的方式這里不做介紹。 

  addEventListener(event,?listener,?useCapture)  

    ·參數定義:event---(事件名稱,如click,不帶on),listener---事件監聽函數,useCapture---是否采用事件捕獲進行事件捕捉,

        默認為false,即采用事件冒泡方式

    addEventListener在?IE11、Chrome?、Firefox、Safari等瀏覽器都得到支持。

  attachEvent(event,listener)  

    ·參數定義:event---(事件名稱,如onclick,帶on),listener---事件監聽函數。

    attachEvent主要用于IE瀏覽器,并且僅在IE10及以下才支持,IE11已經廢了這個方法了(微軟還是挺識趣的,慢慢向標準靠攏)。

?

說了一籮筐定義,下面就用上面這兩個方法通過栗子來解釋一下事件捕獲與事件冒泡的具體表現行為差異。

事件冒泡

栗1:

<html lang="zh-cn">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>js事件機制</title><style>#parent{width: 200px;height:200px;text-align: center;line-height: 3;background: green;}#child{width: 100px;height: 100px;margin: 0 auto;background: orange;}</style></head>
<body><div id="parent">父元素<div id="child">子元素</div></div><script type="text/javascript">var parent = document.getElementById("parent");var child = document.getElementById("child");document.body.addEventListener("click",function(e){console.log("click-body");},false);parent.addEventListener("click",function(e){console.log("click-parent");},false);child.addEventListener("click",function(e){console.log("click-child");},false);</script>
</body>
</html>

通過"addEventListener"方法,采用事件冒泡方式給dom元素注冊click事件,點擊子元素會發生什么呢?如果你對事件冒泡有一定了解的話那你肯定知道上面的代碼會輸出的順序,沒錯,如下圖所示:

事件觸發順序是由內到外的,這就是事件冒泡,雖然只點擊子元素,但是它的父元素也會觸發相應的事件,其實這是合理的,因為子元素在父元素里面,點擊子元素也就相當于變相的點擊了父元素,這樣理解對吧?

這里有同學可能要問了,如果點擊子元素不想觸發父元素的事件怎么辦?肯定可以的,那就是停止事件傳播---event.stopPropagation();

修改栗1的代碼,在子元素的監聽函數中加入停止事件傳播的操作,栗2

child.addEventListener("click",function(e){console.log("click-child");e.stopPropagation();
},false);

在點擊子元素的時候就只彈出了子元素那條信息,父元素的事件沒有觸發,因為事件已經停止傳播了,冒泡階段也就停止了。

事件冒泡差不多就講述完了,別急,捕獲還沒說呢!

事件捕獲

栗3,修改栗子1中的代碼,給parent元素注冊一個捕獲事件,如下

     var parent = document.getElementById("parent");var child = document.getElementById("child");document.body.addEventListener("click",function(e){console.log("click-body");},false);parent.addEventListener("click",function(e){console.log("click-parent---事件傳播");},false);
     //新增事件捕獲事件代碼parent.addEventListener(
"click",function(e){console.log("click-parent--事件捕獲");},true);child.addEventListener("click",function(e){console.log("click-child");},false);

如果你看明白了我前面說的那些,你就知道這個栗子的輸出順序了。

父元素通過事件捕獲的方式注冊了click事件,所以在事件捕獲階段就會觸發,然后到了目標階段,即事件源,之后進行事件傳播,parent同時也用冒泡方式注冊了click事件,所以這里會觸發冒泡事件,最后到根節點。這就是整個事件流程。

?

上面介紹了事件冒泡、事件捕獲、事件傳播,下面講一下如果通過以上三個知識點進行事件委托

?

委托在JQuery中已經得到了實現,即通過$(selector).on(event,childSelector,data,function,map)實現委托,一般用于動態生成的元素,當然JQuery也是通過原聲的js去實現的,下面舉一個簡單的栗子,通過js實現通過parent元素給child元素注冊click事件

var parent = document.getElementById("parent");
var child = document.getElementById("child");
parent.onclick = function(e){if(e.target.id == "child"){console.log("您點擊了child元素")}
}

雖然沒有直接只child元素注冊click事件,可是點擊child元素時卻彈出了提示信息。

到這里是不是對js的事件機制有一定的了解了呢?感覺有幫助的話就看看下面的小黃臉,你懂得哦!

如有錯誤,歡迎指正

如有問題,歡迎提問

?

轉載于:https://www.cnblogs.com/bfgis/p/5460191.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257255.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257255.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257255.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

很棒的HTML5效果實例

2019獨角獸企業重金招聘Python工程師標準>>> http://mrdoob.com/141/Internet_Explorer_with_WebGL 轉載于:https://my.oschina.net/u/3647620/blog/1552495

計算機一級網絡操作題沒點回答,計算機等級一級考試操作題1(附答案)

一、選擇題1、在計算機領域中通常用mips來描述______。a、計算機的運算速度 b、計算機的可靠性 c、計算機的可運行性 d、計算機的可擴充性2、微型計算機存儲系統中&#xff0c;prom是______。a、可讀寫存儲器 b、動態隨機存取存儲器 c、只讀存儲器 d、可編程只讀存儲器3、按161…

模擬 Codeforces Round #297 (Div. 2) A. Vitaliy and Pie

題目傳送門 1 /*2 模擬&#xff1a;這就是一道模擬水題&#xff0c;看到標簽是貪心&#xff0c;還以為錯了呢3 題目倒是很長:)4 */5 #include <cstdio>6 #include <algorithm>7 #include <iostream>8 #include <algorithm>9 #include <cstr…

Socket 之 API函數介紹

1、創建套接字──socket() 應用程序在使用套接字前&#xff0c;首先必須擁有一個套接字&#xff0c;系統調用socket()向應用程序提供創建套接字的手段&#xff0c;其調用格式如下&#xff1a; SOCKET PASCAL FAR socket(int af, int type, int protocol); 該調用要接收三個參…

分配的訪問權限的展臺應用:最佳做法

原文: 分配的訪問權限的展臺應用&#xff1a;最佳做法 best practices guidance for developing a kiosk app for assigned access. 在 Windows 10 中&#xff0c;你可以使用鎖屏框架和分配的訪問權限創建展臺應用&#xff0c;該應用允許用戶與設備上的單個應用進行交互。 本文…

計算機工程 目錄 2014年第1期 pdf,2013科技核心期刊目錄有效期至2014年).pdf

2013科技核心期刊目錄有效期至2014年).pdf中國科技核心期刊(中國科技論文統計源期刊)2013CODE 期刊名稱2013 年新入選F034 ACTA BIOCHIMICA ET BIOPHYSICA SINICAC096 ACTA MATHEMATICA SCIENTIAB030 ACTA MATHEMATICA SINICA ENGLISH SERIESI051 ACTA MATHEMATICAE APPLICATAE…

SQL Server 阻止了對組件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的訪問的解決方案...

今天寫了一個excel表的導入功能&#xff0c;結果在excel表中的內容導入到頁面時報錯&#xff1a;SQL Server 阻止了對組件 Ad Hoc Distributed Queries 的 STATEMENTOpenRowset/OpenDatasource 的訪問&#xff0c;因為此組件已作為此服務器安全配置的一部分而被關閉。系統管…

Mongo客戶端MongoVUE的基本使用

這里沒有涉及到服務器以及客戶端的安裝&#xff0c;文章主要介紹mongo客戶端mongoVUE的使用 一、數據庫連接 點擊綠色加號添加一個連接&#xff0c;輸入name、server、port&#xff0c;點擊save&#xff0c;點擊connect進行連接 二、添加 1.右鍵添加一個Database 2.輸入名稱&am…

Vim雜記:Sublime的配色方案

一、前言                                     愛美之心人皆有之&#xff0c;sublime的配色實在好看&#xff0c;于是希望Vim也能這樣。 二、配置                                     1.下載monok…

計算機一級考試有三科,全國計算機一級考試是一級WPS?Office?一級MS?Office?一級Photoshop?三個任選一個考試嗎?...

滿意答案nanrrui3j2017.08.24采納率&#xff1a;41% 等級&#xff1a;9已幫助&#xff1a;415人全國計算機一級考試是有考試大綱的&#xff0c;按照大綱要求是三科都考。一級MS Office、一級WPS Office、一級Photoshop&#xff0c;一級共三個科目。完全采取上機考試形式&…

mysql索引結構原理、性能分析與優化

摘要&#xff1a; 第一部分&#xff1a;基礎知識 第二部分&#xff1a;MYISAM和INNODB索引結構 1、簡單介紹B-tree B tree樹 2、MyisAM索引結構 3、Annode索引結構 4、MyisAM索引與InnoDB索引相比較 第三部分&#xff1a;MYSQL優化 1、表數據類型選擇 2、sql語句優化 (1) 最…

Docker學習(三):鏡像

2019獨角獸企業重金招聘Python工程師標準>>> 1、簡介 docker運行前需要本地存在對應的鏡像&#xff0c;若鏡像不存在本地&#xff0c;docker會先嘗試從默認的鏡像倉庫下載&#xff08;Docker Hub公共注冊服務器中的倉庫&#xff09;。用戶也可以配置&#xff0c;使用…

系統流程圖

轉載于:https://www.cnblogs.com/ADCARRY/p/5462270.html

一年級下冊計算機教學計劃,【實用】一年級下冊教學計劃4篇

【實用】一年級下冊教學計劃4篇光陰迅速&#xff0c;一眨眼就過去了&#xff0c;我們的教學工作又將抒寫新的篇章&#xff0c;寫好教學計劃才不會讓我們努力的時候迷失方向哦。相信大家又在為寫教學計劃犯愁了吧&#xff0c;下面是小編精心整理的一年級下冊教學計劃4篇&#xf…

Discretized Streams: An Efficient and Fault-Tolerant Model for Stream Processing on Large Clusters

閱讀筆記 概述&#xff1a; 本文同樣發表于2012年。提出了一種稱為離散化數據流(Discretized Streams,D-Streams)的編程模型。該模型提供了一種高級函數式API&#xff0c;具有高度的一致性和強大的容錯能力。基于Spark分布式計算框架&#xff0c;進行擴展實現了一個D-Stream的原…

復習計劃

算法 貪心 二分 模擬 倍增 排序 sort 歸并排序 插入排序 最短路 SPFA Djistra Floyd 最小生成樹 kruskal prim 拓撲排序 tarjan 二分圖 樹的直徑、樹的重心 dfs序 hash 數據結構 棧 隊列 單調隊列 單調棧https://www.luogu.org/problem/show?pid2659 并查集 線段樹 樹狀數組 二…

計算機應用基礎分析與報告,y計算機應用基礎出題分析報告.doc

y計算機應用基礎出題分析報告計算機應用基礎出題分析報告本次計算機應用基礎抽考試題按照2011年甘肅省三校生高考考試標準&#xff0c;重在考查學生對windows xp和office辦公軟件基本概念、基本操作的掌握情況。以充分體現基礎理論和實踐操作相結合為主&#xff0c;深入淺出地將…

mysql left join join right

create table java (name varchar(255)); insert into java values (java1),(java2),(blue); create table mysql (name varchar(255)); insert into mysql values (mysql1),(mysql2),(blue); 1.join 查詢 內聯查詢 查兩個表的內才聯系相同的值select * from java join mysql a…

PowerDesigner中NAME和COMMENT的互相轉換,需要執行語句

原文&#xff1a;http://www.cnblogs.com/yelaiju/archive/2013/04/26/3044828.html由于PDM 的表中 Name 會默認Code 所以很不方便, 所以需要將 StereoType 顯示到表的外面來 打開[工具]->[顯示屬性](英文:Display Preferences) ->Content->Table->右邊面板Columns…

成都計算機中心起名,成都給寶寶起名的地方哪里好

成都給寶寶起名的地方哪里好2018-09-21每一個人都擁有一個好聽大氣的名字&#xff0c;名字作為一個人的標識&#xff0c;是人與人交流的代號&#xff0c;因此有一個好聽寓意大氣的名字是很關鍵的&#xff0c;名字畢竟關乎著對他人的第一印象&#xff0c;所以在起名字方面父母們…