javascript
javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。...
2018年12月13日更新
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><style>ul li{border: 1px solid yellow;}</style> </head> <body> <p hidden>This content is not relevant to this page right now, so should not be seen. Nothing to see here. Nada.</p> <div id="ysr" style="border: 1px solid red;background-color: green;padding: 50px;"><ul id="ljl"><li id="1">aaaaaaaaa</li><li id="2">aaaaaaaaa</li><li id="3">aaaaaaaaa</li><li id="4">aaaaaaaaa</li><li id="5">aaaaaaaaa</li><li id="6">aaaaaaaaa</li><li id="7">aaaaaaaaa</li><li id="8">aaaaaaaaa</li><li id="9">aaaaaaaaa</li></ul> </div> <script>var ljl = document.getElementById('ljl');ljl.onclick = function (ev) {console.log(ev);console.log(ev.target);alert('in');ev.stopPropagation();};function doSth(){alert('---a---');}function doSth2(){alert('---ysr---');}ljl.addEventListener('click',doSth,true)var ysr = document.getElementById('ysr');ysr.addEventListener('click',doSth2,true)ysr.onclick = function (ev) {console.log(ev);console.log(ev.target);alert('in another');}</script> </body> </html>
----------------------------------------------------------------------------------------------------------------------------------------------------------
首先,弄明白js 當中,什么是事件,事件模型在js中是如何設計的。什么是事件冒泡?
什么是“事件冒泡”呢?假設這里有一杯水,水被用某種神奇的方式分成不同顏色的幾層。這時,從最底層冒出了一個氣泡,氣泡會一層一層地上升,直到最頂層。而你不管在水的哪一層觀察都可以看到并捕捉到這個氣泡。好了,把“水”改成“DOM”,把“氣泡”改成“事件”。這就是“事件冒泡”
?
什么是事件委托呢?event delegation : 地址:http://davidwalsh.name/event-delegate
One of the hot methodologies in the JavaScript world is event delegation, and for good reason. ?Event delegation allows you to avoid adding event listeners to specific nodes; ?instead, the event listener is added to one parent. ?That event listener analyzes bubbled events to find a match on child elements. ?The base concept is fairly simple but many people don't understand just?how?event delegation works. ?Let me explain the how event delegation works and provide pure JavaScript example of basic event delegation.
下面是我在csdn找到的一篇解釋,寫的不錯。原文地址:http://blog.csdn.net/iefreer/article/details/8573940
1、Event是什么?
event是用戶操作網頁時發生的交互動作,比如click/move, event除了用戶觸發的動作外,還可以是文檔加載,窗口滾動和大小調整。
2、Event模型是什么?
Event模型指的是瀏覽器如何處理發生的事件。不同的瀏覽器其處理機制也不盡相同,甚至截然相反。
一般而言,某個界面元素發生單個事件,那么事件的處理對象就是該界面元素。
但一個典型的問題是如果該界面元素存在父子元素,而且父子元素也定義了同樣的事件,
這個時候事件該如何處理呢,事件在父子元素之間是如何傳遞的呢,誰會先接收到這個事件,又是誰先處理呢?
?
舉個例子:
----------------------------------- | element1 | | ------------------------- | | |element2 | | | ------------------------- | | | -----------------------------------element2是element1的子元素,兩者都定義了onclick事件。
這就是事件模型(事件序列)要解決的問題。
兩種模型
回到網景和微軟斗爭的年代,兩個公司選擇了不同的道路:
網景選擇的是事件捕獲(event capturing)模型,即網景認為element1首先獲取到事件;
微軟選擇了和其桌面系統類似的消息機制,認為element2有更高的優先權,即事件冒泡(event bubbling),
這兩個模型截然相反,IE僅支持event bubbling. Mozilla, Opera 7等兩種都支持. 更老版本的Opera和iCab兩種都不支持。
你現在也許體會到了什么是互聯網最初那最好也最壞的年代。
?
?
事件捕獲
? ? | | --------------- | |----------------- | element1 ? | | | | ----------- ? ?| |----------- | | |element2 ?\ / | | | ------------------------- | | Event CAPTURING | -----------------------------------看上面箭頭的方向,element1的事件處理器首先被觸發,然后向下傳遞到element2
?
事件冒泡
?
/ \ --------------| |----------------- | element1 | | | | ----------- | |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------與事件捕獲相反,element2的事件處理器會首先被觸發。
?
?
W3C模型
W3C非常理智的處理了這種差異,在兩者之間采取了中和的方法,W3C模型規定任何事件首先會被捕獲直到遇到目標元素,然后再向上返回。
?
? ? | | / \ -----------------| |--| |----------------- | element1 | | | | | | ---------------| |--| |----------- | | |element2 \ / ?| | | | | -------------------------------- | | W3C event model | ------------------------------------------?
WEB開發人員可以通過addEventListener()方法來選擇在哪個階段注冊事件處理器(捕獲階段還是冒泡階段),這個方法在Advanced models中有詳細描述,其最后一個參數為true,則代表事件在捕獲階段被處理,false則代表事件在冒泡階段被處理。
?
比如:
?
element1.addEventListener('click',doSomething2,true) element2.addEventListener('click',doSomething,false)事件首先被element1捕獲,然后執行doSomething2,接著事件傳遞給element2,doSomething被執行,接著,事件冒泡回溯,檢查是否有父元素(element1)定義了冒泡階段的事件處理器,這里沒有,所以事件終止。
?
?
兼容傳統模型
?
在支持W3C DOM的瀏覽器中,傳統的事件注冊被看作是注冊于冒泡階段。
element1.onclick = doSomething2;————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
例子: 原地址:http://www.pureweber.com/article/event-delegation/ <html> <head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><style>.white{background-color:#fff;}#d1{width:400px;height:400px;border:1px solid #000;margin:50px 50px;}#d2{width:300px;height:300px;border:1px solid #000;margin:50px 50px;}#d3{width:200px;height:200px;border:1px solid #000;margin:50px 50px;}#d4{width:100px;height:100px;border:1px solid #000;margin:50px 50px;}</style><script src="./lib/js/jquery-2.1.3.js"></script></head><body> <div id="d1" class="white"><div id="d2" class="white"><div id="d3" class="white"><div id="d4" class="white"></div></div></div> </div> <button id="reset1">重置</button> </body> <script>$('#d4').bind('click', function(e){e.stopPropagation();alert('冒泡被阻止,這塊將不會改變顏色');});jQuery('#d1').click(function(e){var t = jQuery(e.target);var id = t.attr('id');if (id==='d4'){t.css('background-color', 'yellow');} else if (id==='d3') {t.css('background-color', 'green');} else if (id==='d2') {t.css('background-color', 'blue');} else {t.css('background-color', 'red');}});jQuery('#reset1').click(function(){jQuery('.white').css('background-color', '#fff')});/*jQuery('#d4').click(function(){jQuery(this).css('background-color', 'yellow')});jQuery('#d3').click(function(){jQuery(this).css('background-color', 'green')});jQuery('#d2').click(function(){jQuery(this).css('background-color', 'blue')});jQuery('#d1').click(function(){jQuery(this).css('background-color', 'red')});jQuery('#reset1').click(function(){jQuery('.white').css('background-color', '#fff')});*/ </script> </html>
例子說明:注釋的js 作用是顯示出(事件冒泡和事件捕捉的):點擊最小的那個,外面所有的都會被上色。你會發現,點擊里層的正方形,外層所有的正方形都會被上色。因為它們也都捕捉到了點擊事件。。未注釋的是:修改上面的程序,使用事件委托來處理點擊事件。 ?當最頂層捕獲點擊事件時,查看事件來源于哪一層,然后只將那一層涂色。再次點擊每一層,查看實際效果。只有當前點擊的正方形變色了,其他的都毫無反應。都“委托” 給了最頂層的那個div.當然,如果你有這樣嵌套的頁面元素,使用了事件委托,委托到了最頂層,這時需要注意:如果其中某個元素,你不希望它的事件冒泡,那么可以使用某種方式阻止事件的冒泡。在jQuery框架中,可以使用stopPropagation()方法來實現而不必關心瀏覽器兼容性。
事件委托的用途:事件委托是事件冒泡的一個應用,可以減少綁定元素的個數,也不必擔心子節點被替換后可能需要進行重新的事件綁定。因為事件的捕獲和后續代碼的執行已經完全委托給了其父節點。如果頁面中含有大量元素需要綁定事件,這樣做會減少事件綁定數量,為瀏覽器減負,無疑會提高頁面性能。
轉載于:https://www.cnblogs.com/oxspirt/p/4446564.html
總結
以上是生活随笔為你收集整理的javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在存储过程中编写正确的事务处理代码
- 下一篇: 对javascript中的匿名函数的理解