久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

一文搞懂JS中的事件冒泡機制

本篇文章聊聊事件冒泡,帶大家深入了解一下JS中的事件冒泡機制,希望對大家有所幫助!

一文搞懂JS中的事件冒泡機制

1. 事件

在瀏覽器客戶端應(yīng)用平臺,基本生都是以事件驅(qū)動的,即某個事件發(fā)生,然后做出相應(yīng)的動作。

瀏覽器的事件表示的是某些事情發(fā)生的信號。事件的闡述不是本文的重點,尚未了解的朋友,可以自行百度 進行了解,這將有助于更好地理解以下的內(nèi)容 。

2.冒泡機制

什么是冒泡呢?

下面這個圖片大家應(yīng)該心領(lǐng)神會吧,氣泡從水底開始往上升,由深到淺,升到最上面。在上升的過程中,氣泡會經(jīng)過不同深度層次的水。

一文搞懂JS中的事件冒泡機制

相對應(yīng)地:這個氣泡就相當于我們這里的事件,而水則相當于我們的整個dom樹;事件從dom 樹的底層 層層往上傳遞,直至傳遞到dom的根節(jié)點。

簡單案例分析

下面通過一個簡單的例案例來闡述冒泡原理:

定義一個html, 里面有三個簡單的dom 元素:div1,div2, span,div2包含span,div1 包含div2;而它們都在body 下:

<body id="body"> 	<div id="box1" class="box1"> 		<div id="box2" class="box2"> 			<span id="span">This is a span.</span> 		</div> 	</div> </body>

界面原型如下:

一文搞懂JS中的事件冒泡機制

在這個基礎(chǔ)上,我們實現(xiàn)下面的功能:

a、 body添加 click 事件監(jiān)聽,當body捕獲到event事件時,打印出事件發(fā)生的時間和 觸發(fā)事件的節(jié)點信息:

<script type="text/javascript"> 	window.onload = function() { 		document.getElementById("body").addEventListener("click",eventHandler); 	} 	function eventHandler(event) { 		console.log("時間:"+new Date(event.timeStamp)+" 產(chǎn)生事件的節(jié)點:" + event.target.id +"  當前節(jié)點:"+event.currentTarget.id); 	} </script>

當我們依次點擊"This is span",div2,div1,body后,輸出以下信息:

一文搞懂JS中的事件冒泡機制

分析以上的結(jié)果:

無論是body,body 的子元素div1,還是 div的子元素div2,還有 span, 當這些元素被點擊click時,都會產(chǎn)生click事件,并且body都會捕獲到,然后調(diào)用相應(yīng)的事件處理函數(shù)。就像水中的氣泡從底往上冒一樣,事件也會往上傳遞。

事件傳遞的示意圖如下所示:

一文搞懂JS中的事件冒泡機制

一般地,事件在傳遞過程中會有一些信息,這些是事件的組成部分:事件發(fā)生的時間+事件發(fā)生的地點+ 事件的類型+事件的當前處理者+其他信息

一文搞懂JS中的事件冒泡機制

完整的html代碼如下:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script type="text/javascript" src="js/jquery-1.11.0.js"></script> <title>Insert title here</title> <style type="text/css"> .box1 { 	border: green 40px solid; 	width: 300px; 	height: 300px; 	margin: auto; }   .box2 { 	border: yellow 40px solid; 	width: 220px; 	height: 220px; 	margin: auto; }   span { 	position: relative; 	left: 50px; 	top: 50px; 	background-color: rgba(128, 128, 128, 0.22); } </style>   <script type="text/javascript"> 	window.onload = function() { 		document.getElementById("body").addEventListener("click",eventHandler); 	} 	function eventHandler(event) { 		console.log("時間:"+new Date(event.timeStamp)+" 產(chǎn)生事件的節(jié)點:" + event.target.id +"  當前節(jié)點:"+event.currentTarget.id); 	} </script>   </head> <body id="body"> 	<div id="box1" class="box1"> 		<div id="box2" class="box2"> 			<span id="span">This is a span.</span> 		</div> 	</div> </body> </html>

b、終止事件的冒泡

我們現(xiàn)在想實現(xiàn)這樣的功能,在div1 點擊的時候,彈出 "你好,我是最外層div。",點擊div2 的時候,彈出 "你好,我是第二層div";點擊span 的時候,彈出"您好,我是span。"。

由此我們會有下面的javascript片段:

<script type="text/javascript"> 	window.onload = function() { 		document.getElementById("box1").addEventListener("click",function(event){ 			alert("您好,我是最外層div。"); 		}); 		document.getElementById("box2").addEventListener("click",function(event){ 			alert("您好,我是第二層div。"); 		}); 		document.getElementById("span").addEventListener("click",function(event){ 			alert("您好,我是span。"); 		}); 	} </script>

預(yù)期上述代碼會單擊span 的時候,會出來一個彈出框 "您好,我是span。" 是的,確實彈出了這樣的對話框:

一文搞懂JS中的事件冒泡機制

然而,不僅僅會產(chǎn)生這個對話框,當點擊確定后,會依次彈出下列對話框:

一文搞懂JS中的事件冒泡機制 一文搞懂JS中的事件冒泡機制

這顯然不是我們想要的! 我們希望的是點誰顯示誰的信息而已。為什么會出現(xiàn)上述的情況呢? 原因就在于事件的冒泡,點擊span的時候,span 會把產(chǎn)生的事件往上冒泡,作為父節(jié)點的div2 和 祖父節(jié)點的div1也會收到此事件,于是會做出事件響應(yīng),執(zhí)行響應(yīng)函數(shù)。現(xiàn)在問題是發(fā)現(xiàn)了,但是怎么解決呢?

方法一:我們來考慮一個形象一點的情況:水中的一個氣泡正在從底部往上冒,而你現(xiàn)在在水中,不想讓這個氣泡往上冒,怎么辦呢?——把它扎破!沒了氣泡,自然不會往上冒了。類似地,對某一個節(jié)點而言,如果不想它現(xiàn)在處理的事件繼續(xù)往上冒泡的話,我們可以終止冒泡:

在相應(yīng)的處理函數(shù)內(nèi),加入 event.stopPropagation() ,終止事件的廣播分發(fā),這樣事件停留在本節(jié)點,不會再往外傳播了。修改上述的script片段:

<script type="text/javascript"> 	window.onload = function() { 		document.getElementById("box1").addEventListener("click",function(event){ 			alert("您好,我是最外層div。"); 			event.stopPropagation(); 		}); 		document.getElementById("box2").addEventListener("click",function(event){ 			alert("您好,我是第二層div。"); 			event.stopPropagation(); 		}); 		document.getElementById("span").addEventListener("click",function(event){ 			alert("您好,我是span。"); 			event.stopPropagation(); 		}); 	} </script>

經(jīng)過這樣一段代碼,點擊不同元素會有不同的提示,不會出現(xiàn)彈出多個框的情況了。

方法二:事件包含最初觸發(fā)事件的節(jié)點引用 和 當前處理事件節(jié)點的引用,那如果節(jié)點只處理自己觸發(fā)的事件即可,不是自己產(chǎn)生的事件不處理。event.target 引用了產(chǎn)生此event對象的dom 節(jié)點,而event.currrentTarget 則引用了當前處理節(jié)點,我們可以通過這 兩個target 是否相等。

比如span 點擊事件,產(chǎn)生一個event 事件對象,event.target 指向了span元素,span處理此事件時,event.currentTarget 指向的也是span元素,這時判斷兩者相等,則執(zhí)行相應(yīng)的處理函數(shù)。而事件傳遞給 div2 的時候,event.currentTarget變成 div2,這時候判斷二者不相等,即事件不是div2 本身產(chǎn)生的,就不作響應(yīng)處理邏輯。

<script type="text/javascript"> 	window.onload = function() { 		document.getElementById("box1").addEventListener("click",function(event){ 			if(event.target == event.currentTarget) 			{ 			    alert("您好,我是最外層div。"); 			} 		}); 		document.getElementById("box2").addEventListener("click",function(event){ 			if(event.target == event.currentTarget) 			{ 				alert("您好,我是第二層div。"); 			} 		}); 		document.getElementById("span").addEventListener("click",function(event){ 			if(event.target == event.currentTarget) 			{ 			    alert("您好,我是span。"); 				 			} 		}); 	} </script>

比較:

從事件傳遞上看:

  • 方法一在于取消事件冒泡,即當某些節(jié)點取消冒泡后,事件不會再傳遞;

  • 方法二在于不阻止冒泡,過濾需要處理的事件,事件處理后還會繼續(xù)傳遞;

優(yōu)缺點:

  • 方法一缺點:為了實現(xiàn)點擊特定的元素顯示對應(yīng)的信息,方法一要求每個元素的子元素也必須終止事件的冒泡傳遞,即跟別的元素功能上強關(guān)聯(lián),這樣的方法會很脆弱。比如,如果span 元素的處理函數(shù)沒有執(zhí)行冒泡終止,則事件會傳到p2 上,這樣會造成p2 的提示信息;

  • 方法二缺點:方法二為每一個元素都增加了事件監(jiān)聽處理函數(shù),事件的處理邏輯都很相似,即都有判斷 if(event.target == event.currentTarget),這樣存在了很大的代碼冗余,現(xiàn)在是三個元素還好,當有10幾個,上百個又該怎么辦呢?

還有就是為每一個元素都有處理函數(shù),在一定程度上增加邏輯和代碼的復(fù)雜度。

我們再來分析一下方法二:方法二的原理是 元素收到事件后,判斷事件是否符合要求,然后做相應(yīng)的處理,然后事件繼續(xù)冒泡往上傳遞;

既然事件是冒泡傳遞的,那可不可以讓某個父節(jié)點統(tǒng)一處理事件,通過判斷事件的發(fā)生地(即事件產(chǎn)生的節(jié)點),然后做出相應(yīng)的處理呢?答案是可以的,下面通過給body 元素添加事件監(jiān)聽,然后通過判斷event.target 然后對不同的target產(chǎn)生不同的行為。

將方法二的代碼重構(gòu)一下:

<script type="text/javascript"> 	window.onload = function() { 		document.getElementById("body").addEventListener("click",eventPerformed); 	} 	function eventPerformed(event) { 		var target = event.target; 		switch (target.id) { 		case "span":  			alert("您好,我是span。"); 			break; 		case "div1": 			alert("您好,我是第二層div。"); 			break; 		case "div2": 			alert("您好,我是最外層div。"); 			break; 		} 	} </script>

結(jié)果會是點擊不同的元素,只彈出相符合的提示,不會有多余的提示。

通過以上方式,我們把本來每個元素都要有的處理函數(shù),都交給了其祖父節(jié)點body 元素來完成了,也就是說,span,p2,p1 將自己的響應(yīng)邏輯委托給body,讓它來完成相應(yīng)邏輯,自己不實現(xiàn)相應(yīng)邏輯,這個模式,就是所謂的事件委托。

下面是一個示意圖:

一文搞懂JS中的事件冒泡機制

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
欧美国产中文高清| 婷婷综合电影| 正在播放日韩精品| 亚洲最大av| 香蕉视频亚洲一级| 国产欧美日韩| 91精品99| 精品国产美女a久久9999| 亚洲欧美日韩国产一区二区| 久久国产人妖系列| 精品亚洲精品| 亚洲五月综合| 国产毛片久久| 亚洲一区成人| 日韩在线一二三区| 亚洲福利精品| 欧美激情精品| 日韩欧美三区| 午夜精品免费| 国内精品福利| 日韩不卡一区| 丰满少妇一区| 视频一区二区三区入口| 日韩精品视频网| 午夜在线视频一区二区区别| 在线日韩中文| 91看片一区| 国产一区二区三区四区大秀| 国产精品久久乐| 国产亚洲一区二区三区不卡| 欧美日韩 国产精品| 国产精品美女久久久久久不卡| 欧美国产先锋| 日本久久二区| 中文字幕在线看片| 亚洲在线电影| 国产日韩一区二区三免费高清 | 免费看一区二区三区| 亚洲尤物av| 麻豆视频在线观看免费网站黄| 亚洲高清激情| 啪啪国产精品| 欧美日韩xxxx| 国产精品99一区二区三| 快she精品国产999| 999国产精品永久免费视频app| 久久亚洲一区| 国产区精品区| 婷婷综合网站| 亚洲一级黄色| 国产精品日本一区二区三区在线 | 国产视频一区欧美| 久久国内精品| 久久性天堂网| av日韩中文| 国产精品入口久久| 99视频精品| 久久久久蜜桃| 电影91久久久| 国产探花在线精品| 亚洲影院天堂中文av色| 午夜国产一区二区| 欧美国产美女| 久久精品97| 亚洲日产国产精品| 热久久久久久久| 婷婷亚洲精品| 国产欧美一区二区色老头| 国产精品18| 欧美性www| 精品不卡一区| 日韩精品一区二区三区免费观看| 欧美日韩视频| 欧美1级日本1级| 亚洲激情欧美| 日本视频一区二区| 精品丝袜久久| 蜜桃tv一区二区三区| 一区二区三区四区精品视频| 日韩精品91亚洲二区在线观看| 国产一区二区三区不卡av | 国产韩日影视精品| 亚洲午夜黄色| 香蕉精品视频在线观看| 中文字幕一区二区三区日韩精品| 久久久久九九精品影院| 久久国产精品美女| 精品高清久久| 先锋亚洲精品| 国产伦理久久久久久妇女| 伊人久久在线| 婷婷综合电影| 日韩大片在线播放| 亚洲色图综合| 国产一区精品福利| 亚洲视频二区| 日韩伦理福利| 天堂va在线高清一区| 久久精品一区二区国产| 日韩久久99| 欧美日韩色图| 老色鬼精品视频在线观看播放| 午夜日韩av| 欧美激情精品| 亚洲tv在线| 亚洲黄色在线| 欧美aa在线观看| 91av一区| 日韩精品视频网| 久久精品亚洲人成影院 | 中文字幕高清在线播放| 欧美日韩国产高清电影| 欧美一区久久久| 免费在线播放第一区高清av| 亚洲三级精品| 亚洲综合小说| 丝袜亚洲另类欧美| 国产精品日本| 午夜在线精品偷拍| 久久国产精品亚洲77777| 久久亚洲国产| 国产白浆在线免费观看| 久久精品 人人爱| 日本久久二区| 国产精品一卡| 一区二区不卡| 精品日韩毛片| 精品一区二区三区中文字幕视频| 国产夫妻在线| 精品视频网站| 国产日韩亚洲欧美精品| 日本不卡不码高清免费观看| 日韩精品1区2区3区| 久久久国产精品网站| 国产精品1区| 在线精品亚洲欧美日韩国产| 999国产精品999久久久久久| 成人一区而且| 亚洲午夜精品久久久久久app| 在线亚洲激情| 最新亚洲激情| 亚洲一卡久久| 国产精品xxx| 国产在线欧美| 国产精品一线天粉嫩av| bbw在线视频| 久久99伊人| 精品欠久久久中文字幕加勒比| 亚洲一区免费| 麻豆高清免费国产一区| 久久最新视频| 日韩电影二区| 欧美国产不卡| 亚洲青青久久| 不卡av一区二区| 国产日韩专区| 婷婷成人在线| 欧美亚洲国产精品久久| 亚洲专区一区| 亚洲综合精品四区| 日本v片在线高清不卡在线观看| 欧美一区成人| 国产精品激情电影| 国产精品毛片久久| 亚洲一区资源| 亚洲免费成人| 日韩欧美三区| 韩日一区二区| 日韩中文在线电影| 99riav国产精品| 日韩一区二区三免费高清在线观看| 视频精品一区| 国产亚洲第一伦理第一区| 国产精品毛片久久| 特黄毛片在线观看| 亚洲一区二区成人| 久久影院一区二区三区| 精品中文一区| 欧美影院精品| 久久激情婷婷| 欧美自拍一区| 亚洲精品a级片| 国产精品探花在线观看| 日韩精品dvd| 中文字幕视频精品一区二区三区| 91国内精品| 九九精品调教| 日韩中文字幕一区二区高清99| 亚洲最新无码中文字幕久久| 黑丝一区二区三区| 日韩精品午夜| 电影91久久久| 亚洲专区视频| 成人在线视频区| 日韩中文字幕一区二区三区| 国产成人精选| 久久精品国产福利| 日本欧美在线看| 成人国产精选| 日韩精品导航|