摘要:和下面的代碼完全等價阻止默認事件阻止傳播但是如果頁面中有,你在它的父元素任何一層,包括自己,添加了組織默認事件那么這個就沒辦法被。
上一次學習了DOM 的事件,理解了冒泡事件和捕獲事件,觸發的機制,今天學習一下具體的應用場景,或者說在哪個地方容易踩坑。
做一個小demo,點擊按鈕出現浮層,點擊其它地方關閉浮層,寫一個簡單css
浮層
那現在我要點擊頁面空白地方關閉呢?該用什么方法,很容易想到監聽文檔,如下代碼
document.addEventListener("click",function(){ popover.stely.display = "none"; });
但是實際上這樣寫了之后,按鈕都失效了,怎么點都沒有反應。這是為什么呢?
理解上一篇講的捕獲和冒泡事件后就很好理解這點了,可以DOM事件之捕獲、冒泡。
我們沒有指定監聽是在捕獲還是冒泡階段,瀏覽器默認是冒泡階段,當我們點擊按鈕時,捕獲階段沒有發生什么時候,但是冒泡階段就不一樣了,首先button上函數先觸發,然后document上函數也觸發了,導致準備出現的浮層又被隱藏了。
那你可能要問,button上的事件執行了沒?其實這兩個事件都執行了,只是時間太短,瀏覽器默認一起執行了,可以在里面加一個debugger,就可以看到了。
clickMe.addEventListener("click",function(){ popover.style.display = "block"; });
那該怎么解決呢?最簡單的方法是,除了要執行popover.style.display = "block",還要阻止事件傳播
clickMe.addEventlistener("click",function(){ popover.style.display = "block"; }); popover.addEventListener("click",function(e){ e.stopPropagation(); });
這里為什么添加在按鈕的父元素上面呢?如果不添加在父元素上面,點擊浮層的時候,浮層也會被關閉。
如果頁面上有很多監聽器的話,這個方法是比較浪費內存的,比較省內存的方法用JQuery 做
$(clickMe).on("click",function(){ $(popover).show(); $(document).one("click",function(){ $(popover).hide(); }); }); $(wrapper).on("click",function(e){ e.stopPropagation(); })
一開始不監聽,只在popover`show`的時候監聽一次,馬上關掉,這叫做清理戰場。
$(wrapper).on("click",false) 和下面的代碼完全等價
$(wrapper).on("click",function(e){ e.preventDefault(); //阻止默認事件 e.stopPropagation(); //阻止傳播 })
但是如果頁面中有checkbox,你在它的父元素任何一層,包括checkbox自己,添加了組織默認事件那么這個checkbox就沒辦法被check。
這里有個問題,如果沒有阻止事件傳播,向下面這樣,會發生什么事情呢?
$(clickMe).on("click",function(){ $(popover).show(); $(document).one("click",funtion(){ $(popover).hide(); }); });
當然了,和之前一樣,什么事情也不會發生,那當我點擊按鈕之后里面都發生了那些事情呢?
當我點擊了按鈕之后,它會做兩件事情,首先把popover`show出來,然后把hide函數添加到document上面,當事件傳播到document`,就會又把它給隱藏了。
可以給它添加一個setTimeout()函數來解決這個問題
$(clickMe).on("click",function(){ $(popover).show(); setTimeout(function(){ $(document).one("click",function(){ $(popover).hide(); }) },0) });
setTimeout(fn,0)這個0不是馬上執行,而是盡快執行,具體是在冒泡結束在執行這里的函數,也就是說,當冒泡結束后,在把監聽事件添加到document上面,等待用戶下次點擊在執行。
用 jQuery 做事件冒泡
總結:
同時監聽button和document,點啥都沒反應,因為兩個函數都執行了,用阻止事件傳播解決了,比較浪費內存
好一定的方法是用jQuery 做,點擊button后在監聽document,關閉了就不再監聽,不阻止事件傳播,點啥也沒反應,兩種解決方法:一種是阻止事件傳播,另一種是添加一個setTimeout()函數。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95225.html
摘要:目標階段真正點擊的元素的事件發生了兩次,因為在上面的代碼中,既在捕獲階段綁定了事件,又在冒泡階段綁定了事件,所以發生了兩次。所以很明顯用直接綁定的事件發生在了冒泡階段。 如果對事件大概了解,可能知道有事件冒泡這回事,但是冒泡、捕獲、傳播這些機制可能還沒有深入的研究實踐一下,我抽時間整理了一下相關的知識。 本文主要對事件機制一些細節進行討論,過于基礎的事件綁定知識方法沒有介紹。 特別少...
摘要:事件處理程序事件偵聽器的設定級級首先講級事件處理程序對事件的方式被稱為事件處理程序或事件偵聽器,但這兩者之間是有區別的。此外,不能對事件目標事件類型執行階段都相同的對象注冊多個相同的事件偵聽器。 關于這一篇章有太多對于我來說雜且亂的知識點,單單是分別DOM層級劃分我看過的文章就有(0,2,3)的,(0,2)的,由于自己知識掌握還很薄弱所以只能參考別人文章結合自己理解來寫,這其中也涉及到...
摘要:見下圖更直觀在事件流中,事件的目標在捕獲階段不會接受到事件,這意味著在捕獲階段,事件從到后就停止了。下一個階段是目標階段,于是事件在上發生,并在事件處理中被看成是冒泡階段的一部分,然后,冒泡階段發生,事件又傳回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕獲 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是從頁面中接受事件的順序 2.DOM事件流的三個階...
摘要:見下圖更直觀在事件流中,事件的目標在捕獲階段不會接受到事件,這意味著在捕獲階段,事件從到后就停止了。下一個階段是目標階段,于是事件在上發生,并在事件處理中被看成是冒泡階段的一部分,然后,冒泡階段發生,事件又傳回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕獲 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是從頁面中接受事件的順序 2.DOM事件流的三個階...
摘要:見下圖更直觀在事件流中,事件的目標在捕獲階段不會接受到事件,這意味著在捕獲階段,事件從到后就停止了。下一個階段是目標階段,于是事件在上發生,并在事件處理中被看成是冒泡階段的一部分,然后,冒泡階段發生,事件又傳回。 CONTENTS DOM事件流 事件冒泡 阻止冒泡 事件捕獲 事件委托 DOM事件流 1.什么是事件流? 事件流所描述的是從頁面中接受事件的順序 2.DOM事件流的三個階...
閱讀 3551·2021-10-09 09:43
閱讀 6149·2021-09-07 10:15
閱讀 2746·2019-08-30 14:03
閱讀 3074·2019-08-29 11:01
閱讀 1715·2019-08-29 10:56
閱讀 1074·2019-08-28 17:52
閱讀 3502·2019-08-26 11:42
閱讀 2547·2019-08-26 10:33