日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

浏览器事件流

發布時間:2023/12/20 HTML 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浏览器事件流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

事件流描述的是從頁面中接受事件的順序。但有意思的是,IE和Netscape開發團隊居然提出了兩個截然相反的事件流概念。

  1、IE的事件流是 事件冒泡流,

  ?2、標準的瀏覽器事件流是 事件捕獲流。

? ? ?不過addEventLister給出了第三個參數同時支持冒泡與捕獲,下文將介紹

?

事件冒泡

ie 的事件流叫事件冒泡,也就是說事件的傳播為:從事件開始的具體元素,一級級往上傳播到較為不具體的節點。案例如下:

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>事件冒泡</title> </head> <body><div><p>點我</p></div> </body> </html>

當我們點擊P元素時,事件是這樣傳播的:

(1) p

(2) div

(3) body

(4) html

(5) document

現代瀏覽器都支持事件冒泡,IE9、Firefox、Chrome和Safari則將事件一直冒泡到window對象。

?

事件捕獲

? ?Netscape團隊提出的另一種事件流叫做事件捕獲。它的原理剛好和事件冒泡相反,它的用意在于在事件到達預定目標之前捕獲它,而最具體的節點應該是最后才接收到事件的。

比如還是上面的案例,當點擊P元素時,事件的傳播方向就變成了這樣:

(1) document

(2) html

(3) body

(4) div

(5) p

?

IE9、Firefox、Chrome和Safari目前也支持這種事件流模型,但是有些老版本的瀏覽器不支持,所以很少人使用事件捕獲,而是用事件冒泡的多一點。

?

DOM事件流

?  "DOM2級事件"規定的事件流包括三個階段:事件捕獲階段、處于目標階段、事件冒泡階段。

  首先發生的事件捕獲,為截獲事件提供機會。然后是實際的目標接受事件。最后一個階段是時間冒泡階段,可以在這個階段對事件做出響應。以前面的例子,則會按下圖順序觸發事件。

  圖1-1(圖片來源于課本,所以沒有上面案例的p標簽)

  在DOM事件流中,事件的目標在捕獲階段不會接受到事件。這意味著在捕獲階段,事件從document到p后就定停止了。

  下一個階段是處于目標階段,于是事件在p上發生,并在事件處理中被看成冒泡階段的一部分。然后,冒泡階段發生,事件又傳播回document。??

? ? ?多數支持DOM事件流的瀏覽器都實現了一種特定的行為;即使“DOM2級事件”規范明確要求捕獲階段不會涉及事件目標,但IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都會在捕獲階段觸發事件對象上的事件。結果,就是有兩個機會在目標對象上操作事件

?

事件處理程序

事件就是用戶或者瀏覽器自身執行某種動作,比如click、load、mouseover。 而響應某個事件的函數就叫做事件處理程序(事件監聽器),事件處理程序的名字以on開頭,click=>onclick、load=>onloadDOM2提供了兩個方法來讓我們處理和刪除事件處理程序的操作:addEventListener()和removeEventListener btn.addEventListener(eventType, function () { }, false);該方法應用至dom節點 第一個參數為事件名 第二個為事件處理程序 第三個為布爾值,true為事件捕獲階段調用事件處理程序,false為事件冒泡階段調用事件處理程序

?

使用例子如下:

var btn = document.getElementById(‘btn‘);btn.addEventListener(‘click‘, function () {alert(‘事件捕獲‘);}, true);btn.addEventListener(‘click‘, function () {alert(‘事件冒泡‘);}, false);

依次彈出“事件捕獲”和“事件冒泡”,在這里的第一反應就是,他們有先后順序嗎?

于是我反過來寫:

var btn = document.getElementById(‘btn‘);btn.addEventListener(‘click‘, function () {alert(‘事件冒泡‘);}, false);btn.addEventListener(‘click‘, function () {alert(‘事件捕獲‘);}, true);

依次彈出的是:“事件冒泡”和“事件捕獲”;到底有沒有先后順序呢?繼續往下走

這次是這樣的寫法:

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>事件冒泡</title> </head> <body><div><p id="parEle">我是父元素 <span id="sonEle">我是子元素</span></p></div> </body> </html> <script type="text/javascript"> var sonEle = document.getElementById(‘sonEle‘); var parEle = document.getElementById(‘parEle‘);parEle.addEventListener(‘click‘, function () {alert(‘父級 冒泡‘); }, false); parEle.addEventListener(‘click‘, function () {alert(‘父級 捕獲‘); }, true);sonEle.addEventListener(‘click‘, function () {alert(‘子級冒泡‘); }, false); sonEle.addEventListener(‘click‘, function () {alert(‘子級捕獲‘); }, true);</script>

當點擊“我是子元素” 時,彈出的順序是:“父級捕獲”--》“子級冒泡”--》“子集捕獲”--》“父集冒泡”;

這里可以說明,當點擊子元素時,父級的執行順序是先捕獲,后冒泡的。

  綜合前面的代碼,我們可以得出一個小小的結論:

  當容器元素及嵌套元素,即在捕獲階段又在冒泡階段調用事件處理程序時:事件按DOM事件流的順序執行事件處理程序,也就是如圖1-1所示

  且當事件處于目標階段時,事件調用順序決定于綁定事件的書寫順序,按上面的例子為,先調用冒泡階段的事件處理程序,再調用捕獲階段的事件處理程序。依次alert出“子集冒泡”,“子集捕獲”。

?

刪除一個事件處理程序,用removeEventListener。例:

var btn=document.getElementById(‘myBtn‘); var myFn=function(){alert(this.id); } btn.addEventListener(‘click‘,myFn,false); btn.removeEventListener(‘click‘,myFn,false);

?

注意點:為了最大限度的兼容,大多是情況下都是將事件處理程序添加到事件冒泡階段。不是特別需要,不建議在事件捕獲階段注冊事件處理程序

?

兼容ie瀏覽器寫法:

?

ie添加和刪除事件處理程序的寫法有點小區別,所以用以下代碼可以做個兼容性處理:

var EventUtil = {addHandler: function (el, type, handler) {if (el.addEventListener) {el.addEventListener(type, handler, false);} else {el.attachEvent(‘on‘ + type, handler);}},removeHandler: function (el, type, handler) {if (el.removeEventListener) {el.removeEventListerner(type, handler, false);} else {el.detachEvent(‘on‘ + type, handler);}} };

用法和前面的類似:

EventUtil.addHandler(‘btn‘,‘click‘,handler);

?

?

事件對象

觸發dom上的某個事件時,會產生一個事件對象,里面包含著所有和事件有關的信息。

比較常用的有以下幾個:

currentTarget 事件處理程序當前正在處理事件的那個元素(始終等于this)preventDefault 取消事件默認行為,比如鏈接的跳轉stopPropagation 取消事件冒泡target 事件的目標

  

兼容ie的事件對象:

var EventUtil = {addHandler: function (el, type, handler) {if (el.addEventListener) {el.addEventListener(type, handler, false);} else if (el.attachEvent) {el.attachEvent(‘on‘ + type, handler);} else {el[‘on‘ + type] = handler;}},removeHandler: function (el, type, handler) {if (el.removeEventListener) {el.removeEventListerner(type, handler, false);} else if (el.detachEvent) {el.detachEvent(‘on‘ + type, handler);} else {el[‘on‘ + type] = null;}},getEvent: function (e) {return e ? e : window.event;},getTarget: function (e) {return e.target ? e.target : e.srcElement;},preventDefault: function (e) {if (e.preventDefault) {e.preventDefault();} else {e.returnValue = false;}},stopPropagation: function (e) {if (e.stopPropagation) {e.stopPropagation();} else {e.cancelBubble = true;}} };

?

?

其他

?

html5事件之 beforeunload

在頁面卸載前觸發,就像編輯博客園文章未保存是彈出的提示框一樣。

?

html5事件之 DOMContentLoaded事件

支持頁面下載前添加事件,而不需要等待圖片,css文件,或者其他文件加載完畢才執行。可以讓用戶能夠盡早的與用戶進行交互。

EventUtil.addHandler(document,‘DOMContentLoaded‘,function(){alert(‘我可以先執行,哈哈‘) })

?

事件委托:

? ?每個函數都是對象,都會占用內存,內存中的對象越多,性能就越差。對事件處理程序過多問題的解決方案就是事件委托。

? ?事件委托利用事件冒泡,只指定一個事件處理程序即可,就可以管理某一個類型的所有事件。例如:

有三個li,都需要一個click事件,此時不需要給每個li都綁定click事件,主要給他的父級 ul增加一個綁定事件即可。這樣點擊li,利用冒泡,直接觸發ul的click,只要判斷是哪個li的id

點擊即可。而不需要三個li都綁定click事件。

<ul id="myLinks"><li id="myLi1">text1</li><li id="myLi2">text2</li><li id="myLi3">text3</li> </ul>

?

事件委托原理:事件冒泡機制。 優點:1.可以大量節省內存占用,減少事件注冊。比如ul上代理所有li的click事件就很不錯。 2.可以實現當新增子對象時,無需再對其進行事件綁定,對于動態內容部分尤為合適 缺點:事件代理的常用應用應該僅限于上述需求,如果把所有事件都用事件代理,可能會出現事件誤判。即本不該被觸發的事件被綁定上了事件。

二、事件委托如何工作?

我們現在的疑問是:ul元素如何知道li元素點擊了呢?

很簡單,由于所有li元素都是ul元素的子節點,故他們的事件會冒泡,無論點擊哪個li元素,實際上都相當于點擊了ul元素。

現在產生了另一個問題:ul元素如何知道是在哪個li元素上點擊的呢?

我們很容易想到,在ul的事件處理程序中檢測事件對象的target屬性,就可以得到真正點擊的目標元素。

三、事件委托的優點

首先,我們看到添加的事件處理程序減少,可以只有一個事件處理程序。由于每個函數都是對象,對象會占用內存,內存的占用關系到性能。因此第一個優點是:

減少了內存占用,性能更好;

在訪問DOM方面,也使得DOM訪問次數減少。試想一下,如果要為許多的DOM元素綁定事件,自然需要多次訪問DOM元素,設置事件處理程序所需時間更長,整個頁面就緒需要的時間越多。因此第二個優點是:

設置事件處理程序所需時間更少,加快了整個頁面的交互就緒時間。

假使我們將事件處理程序綁定到document對象上,只要可單擊的元素呈現在頁面上,就可以立即具備適當的功能。即還會有一個額外的優點:

document很快就可以訪問,而且可以在頁面生命周期的任何時點添加事件處理程序,而不用等待其他事件完成如DOMContentLoaded、load事件。

總結

以上是生活随笔為你收集整理的浏览器事件流的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。