• <center id="sm46c"></center>
  • <dfn id="sm46c"></dfn>
  • <strike id="sm46c"></strike>
  • <cite id="sm46c"><source id="sm46c"></source></cite>
    • <strike id="sm46c"><source id="sm46c"></source></strike>
      <option id="sm46c"></option>
      国产精品天天看天天狠,女高中生强奷系列在线播放,久久无码免费的a毛片大全,国产日韩综合av在线,亚洲国产中文综合专区在,特殊重囗味sm在线观看无码,中文字幕一区二区三区四区在线,无码任你躁久久久久久老妇蜜桃

      [EX]事件捕獲,事件冒泡,事件委托

      2018-4-17    seo達(dá)人

      如果您想訂閱本博客內(nèi)容,每天自動(dòng)發(fā)到您的郵箱中, 請點(diǎn)這里

      1事件流

      JavaScript與HTML之間的交互是通過事件實(shí)現(xiàn)的。事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特定的交互瞬間。可以使用偵聽器來預(yù)訂事件,以便事件發(fā)生時(shí)執(zhí)行相應(yīng)的代碼。 
       
      事件流的起源:就是在瀏覽器發(fā)展到第四代的時(shí)候,瀏覽器開發(fā)團(tuán)隊(duì)遇到一個(gè)問題:頁面的哪一部分會擁有某個(gè)特定的事件?要明白這個(gè)問題問的是什么,可以想象畫在一張紙上的一組同心圓。如果你把手指放在圓心上,那么你的手指指向的不是一個(gè)圓,而是紙上的所有圓。也就是說如果單擊了頁面的某個(gè)按鈕,同時(shí)也單擊了按鈕的容器元素,甚至單擊了整個(gè)頁面。不過呢,IE提出的是冒泡流,而網(wǎng)景提出的是捕獲流。

      示例:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件流</title> <style type="text/css"> #content{width: 150px;height: 150px;background-color: red;} #btn{width: 80px;height: 80px;background-color: green;} </style> </head> <body> <div id="content">content <div id="btn">button</div> </div> <script type="text/javascript"> var content = document.getElementById("content"); var btn = document.getElementById('btn');
              btn.onclick = function(){ alert("btn");
              };
              content.onclick = function(){ alert("content");
              };
              document.onclick = function(){ alert("document");
              } </script> </body> </html>
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30

      如果點(diǎn)擊容器#btn,則彈出的順序是:btn-content-document;如果點(diǎn)擊的是容器#content,則彈出的是content-document;如果點(diǎn)擊的是document,彈出的是document。

      由此可以看出JavaScript的事件流機(jī)制

      前面說過,IE提出的是冒泡流,而網(wǎng)景提出的是捕獲流,后來在W3C組織的統(tǒng)一之下,JS支持了冒泡流和捕獲流,但是目前低版本的IE瀏覽器還是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以為了能夠兼容更多的瀏覽器,建議大家使用冒泡流。

      JS事件流原理圖如下: 
       
      這里寫圖片描述 


      2事件冒泡與事件捕獲

      由此可以知道:

      1、一個(gè)完整的JS事件流是從window開始,最后回到window的一個(gè)過程

      2、事件流被分為三個(gè)階段(1~5)捕獲過程、(5~6)目標(biāo)過程、(6~10)冒泡過程

      示例:

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> #wrapDiv, #innerP, #textSpan{ margin: 5px;padding: 5px;box-sizing: border-box;cursor: default; } #wrapDiv{ width: 300px;height: 300px;border: indianred 3px solid; } #innerP{ width: 200px;height: 200px;border: hotpink 3px solid; } #textSpan{ display: block;width: 100px;height: 100px;border: orange 3px solid; } </style> </head> <body> <div id="wrapDiv">wrapDiv <p id="innerP">innerP <span id="textSpan">textSpan</span> </p> </div> <script> var wrapDiv = document.getElementById("wrapDiv"); var innerP = document.getElementById("innerP"); var textSpan = document.getElementById("textSpan"); // 捕獲階段綁定事件 window.addEventListener("click", function(e){ console.log("window 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true);
      
          document.addEventListener("click", function(e){ console.log("document 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true);
      
          document.documentElement.addEventListener("click", function(e){ console.log("documentElement 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true);
      
          document.body.addEventListener("click", function(e){ console.log("body 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true);
      
          wrapDiv.addEventListener("click", function(e){ console.log("wrapDiv 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true);
      
          innerP.addEventListener("click", function(e){ console.log("innerP 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true);
      
          textSpan.addEventListener("click", function(e){ console.log("textSpan 捕獲", e.target.nodeName, e.currentTarget.nodeName);
          }, true); // 冒泡階段綁定的事件 window.addEventListener("click", function(e){ console.log("window 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false);
      
          document.addEventListener("click", function(e){ console.log("document 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false);
      
          document.documentElement.addEventListener("click", function(e){ console.log("documentElement 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false);
      
          document.body.addEventListener("click", function(e){ console.log("body 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false);
      
          wrapDiv.addEventListener("click", function(e){ console.log("wrapDiv 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false);
      
          innerP.addEventListener("click", function(e){ console.log("innerP 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false);
      
          textSpan.addEventListener("click", function(e){ console.log("textSpan 冒泡", e.target.nodeName, e.currentTarget.nodeName);
          }, false); </script> </body> </html>
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91

      這個(gè)時(shí)候,如果點(diǎn)擊一下textSpan這個(gè)元素,控制臺會打印出這樣的內(nèi)容: 
       
      這里寫圖片描述

      從上面所畫的事件傳播的過程能夠看出來,當(dāng)點(diǎn)擊鼠標(biāo)后,會先發(fā)生事件的捕獲

      · 捕獲階段:首先window會獲捕獲到事件,之后document、documentElement、body會捕獲到,再之后就是在body中DOM元素一層一層的捕獲到事件,有wrapDiv、innerP。

      · 目標(biāo)階段:真正點(diǎn)擊的元素textSpan的事件發(fā)生了兩次,因?yàn)樵谏厦娴腏avaScript代碼中,textSapn既在捕獲階段綁定了事件,又在冒泡階段綁定了事件,所以發(fā)生了兩次。但是這里有一點(diǎn)是需要注意,在目標(biāo)階段并不一定先發(fā)生在捕獲階段所綁定的事件,而是先綁定的事件發(fā)生,一會會解釋一下。

      · 冒泡階段:會和捕獲階段相反的步驟將事件一步一步的冒泡到window

      上述代碼中的兩個(gè)屬性:e.target和e.currentTarget

      target和currentTarget都是event上面的屬性,target是真正發(fā)生事件的DOM元素,而currentTarget是當(dāng)前事件發(fā)生在哪個(gè)DOM元素上。

      可以結(jié)合控制臺打印出來的信息理解下,目標(biāo)階段也就是 target == currentTarget的時(shí)候。我沒有打印它們兩個(gè)因?yàn)樘L了,所以打印了它們的nodeName,但是由于window沒有nodeName這個(gè)屬性,所以是undefined。

      那可能有一個(gè)疑問,我們不用addEventListener綁定的事件會發(fā)生在哪個(gè)階段呢,我們來一個(gè)測試,順便再演示一下我在上面的目標(biāo)階段所說的目標(biāo)階段并不一定先發(fā)生捕獲階段所綁定的事件是怎么一回事。

      <script>
          var wrapDiv = document.getElementById("wrapDiv"); var innerP = document.getElementById("innerP"); var textSpan = document.getElementById("textSpan"); // 測試直接綁定的事件到底發(fā)生在哪個(gè)階段
          wrapDiv.onclick = function(){
              console.log("wrapDiv onclick 測試直接綁定的事件到底發(fā)生在哪個(gè)階段")
          }; // 捕獲階段綁定事件
          window.addEventListener("click", function(e){
              console.log("window 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); document.addEventListener("click", function(e){
              console.log("document 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); document.documentElement.addEventListener("click", function(e){
              console.log("documentElement 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); document.body.addEventListener("click", function(e){
              console.log("body 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); wrapDiv.addEventListener("click", function(e){
              console.log("wrapDiv 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); innerP.addEventListener("click", function(e){
              console.log("innerP 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); textSpan.addEventListener("click", function(){
              console.log("textSpan 冒泡 在捕獲之前綁定的")
          }, false); textSpan.onclick = function(){
              console.log("textSpan onclick")
          }; textSpan.addEventListener("click", function(e){
              console.log("textSpan 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); // 冒泡階段綁定的事件
          window.addEventListener("click", function(e){
              console.log("window 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); document.addEventListener("click", function(e){
              console.log("document 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); document.documentElement.addEventListener("click", function(e){
              console.log("documentElement 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); document.body.addEventListener("click", function(e){
              console.log("body 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); wrapDiv.addEventListener("click", function(e){
              console.log("wrapDiv 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); innerP.addEventListener("click", function(e){
              console.log("innerP 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); textSpan.addEventListener("click", function(e){
              console.log("textSpan 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); </script>
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76

      控制臺打印如下:

      這里寫圖片描述

      · textSpan是被點(diǎn)擊的元素,也就是目標(biāo)元素,所有在textSpan上綁定的事件都會發(fā)生在目標(biāo)階段,在綁定捕獲代碼之前寫了綁定的冒泡階段的代碼,所以在目標(biāo)元素上就不會遵守先發(fā)生捕獲后發(fā)生冒泡這一規(guī)則,而是先綁定的事件先發(fā)生。 

      [在目標(biāo)元素上就不會遵守先發(fā)生捕獲后發(fā)生冒泡這一規(guī)則,而是先綁定的事件先發(fā)生。]

      · 由于wrapDiv不是目標(biāo)元素,所以它上面綁定的事件會遵守先發(fā)生捕獲后發(fā)生冒泡的規(guī)則。所以很明顯用onclick直接綁定的事件發(fā)生在了冒泡階段。


      3事件綁定

      1、直接獲取元素綁定:

      element.onclick = function(e){
              // ... };
          
      • 1
      • 2
      • 3

      優(yōu)點(diǎn):簡單和穩(wěn)定,可以確保它在你使用的不同瀏覽器中運(yùn)作一致;處理事件時(shí),this關(guān)鍵字引用的是當(dāng)前元素,這很有幫助。

      缺點(diǎn):只會在事件冒泡中運(yùn)行一個(gè)元素一次只能綁定一個(gè)事件處理函數(shù),新綁定的事件處理函數(shù)會覆蓋舊的事件處理函數(shù);事件對象參數(shù)(e)僅非IE瀏覽器可用。


      2、直接在元素里面使用事件屬性

      3、W3C方法:

      element.addEventListener('click', function(e){
              // ... }, false);
          
      • 1
      • 2
      • 3

      優(yōu)點(diǎn):該方法同時(shí)支持事件處理的捕獲和冒泡階段;事件階段取決于addEventListener最后的參數(shù)設(shè)置:false (冒泡) 或 true (捕獲);在事件處理函數(shù)內(nèi)部,this關(guān)鍵字引用當(dāng)前元素;事件對象總是可以通過處理函數(shù)的第一個(gè)參數(shù)(e)捕獲;可以為同一個(gè)元素綁定你所希望的多個(gè)事件,同時(shí)并不會覆蓋先前綁定的事件

      缺點(diǎn):IE不支持,你必須使用IE的attachEvent函數(shù)替代。


      IE下的方法:

      element.attachEvent('onclick', function(){
              // ... });
          
      • 1
      • 2
      • 3

      優(yōu)點(diǎn):可以為同一個(gè)元素綁定你所希望的多個(gè)事件,同時(shí)并不會覆蓋先前綁定的事件。 
       
      缺點(diǎn):IE僅支持事件捕獲的冒泡階段;事件監(jiān)聽函數(shù)內(nèi)的this關(guān)鍵字指向了window對象,而不是當(dāng)前元素(IE的一個(gè)巨大缺點(diǎn));事件對象僅存在與window.event參數(shù)中;事件必須以ontype的形式命名,比如,onclick而非click;僅IE可用,你必須在非IE瀏覽器中使用W3C的addEventListener。

      注意:不是意味這低版本的ie沒有事件捕獲,它也是先發(fā)生事件捕獲,再發(fā)生事件冒泡,只不過這個(gè)過程無法通過程序控制。 


      4解除事件

      通用:

      element.removeEventListener('click', function(e){
              // ... }, false);
          
      • 1
      • 2
      • 3

      IE:

      element.detachEvent('onclick', function(){
              // ... });
          
      • 1
      • 2
      • 3

      5阻止事件傳播

      在支持addEventListener()的瀏覽器中,可以調(diào)用事件對象的stopPropagation()方法以阻止事件的繼續(xù)傳播。如果在同一對象上定義了其他處理程序,剩下的處理程序?qū)⒁琅f被調(diào)用,但調(diào)用stopPropagation()之后任何其他對象上的事件處理程序?qū)⒉粫徽{(diào)用。不僅可以阻止事件在冒泡階段的傳播,還能阻止事件在捕獲階段的傳播。

      IE9之前的IE不支持stopPropagation()方法,而是設(shè)置事件對象cancelBubble屬性為true來實(shí)現(xiàn)阻止事件進(jìn)一步傳播。

      <script>
          var wrapDiv = document.getElementById("wrapDiv"); var innerP = document.getElementById("innerP"); var textSpan = document.getElementById("textSpan"); // 測試直接綁定的事件到底發(fā)生在哪個(gè)階段
          wrapDiv.onclick = function(){
              console.log("wrapDiv onclick 測試直接綁定的事件到底發(fā)生在哪個(gè)階段")
          }; // 捕獲階段綁定事件
          window.addEventListener("click", function(e){
              console.log("window 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); document.addEventListener("click", function(e){
              console.log("document 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); document.documentElement.addEventListener("click", function(e){
              console.log("documentElement 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); document.body.addEventListener("click", function(e){
              console.log("body 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); wrapDiv.addEventListener("click", function(e){
              console.log("wrapDiv 捕獲", e.target.nodeName, e.currentTarget.nodeName); // 在捕獲階段阻止事件的傳播
              e.stopPropagation(); }, true); innerP.addEventListener("click", function(e){
              console.log("innerP 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); textSpan.addEventListener("click", function(){
              console.log("textSpan 冒泡 在捕獲之前綁定的")
          }, false); textSpan.onclick = function(){
              console.log("textSpan onclick")
          }; textSpan.addEventListener("click", function(e){
              console.log("textSpan 捕獲", e.target.nodeName, e.currentTarget.nodeName); }, true); // 冒泡階段綁定的事件
          window.addEventListener("click", function(e){
              console.log("window 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); document.addEventListener("click", function(e){
              console.log("document 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); document.documentElement.addEventListener("click", function(e){
              console.log("documentElement 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); document.body.addEventListener("click", function(e){
              console.log("body 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); wrapDiv.addEventListener("click", function(e){
              console.log("wrapDiv 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); innerP.addEventListener("click", function(e){
              console.log("innerP 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); textSpan.addEventListener("click", function(e){
              console.log("textSpan 冒泡", e.target.nodeName, e.currentTarget.nodeName); }, false); </script>
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78

      這里寫圖片描述

      實(shí)際上我們點(diǎn)擊的是textSpan,但是由于在捕獲階段事件就被阻止了傳播,所以在textSpan上綁定的事件根本就沒有發(fā)生,冒泡階段綁定的事件自然也不會發(fā)生,因?yàn)樽柚故录诓东@階段傳播的特性,e.stopPropagation()很少用到在捕獲階段去阻止事件的傳播,大家就以為e.stopPropagation()只能阻止事件在冒泡階段傳播。 


      6阻止事件的默認(rèn)行為

      e.preventDefault()可以阻止事件的默認(rèn)行為發(fā)生,默認(rèn)行為是指:點(diǎn)擊a標(biāo)簽就轉(zhuǎn)跳到其他頁面、拖拽一個(gè)圖片到瀏覽器會自動(dòng)打開、點(diǎn)擊表單的提交按鈕會提交表單等等,因?yàn)橛械臅r(shí)候我們并不希望發(fā)生這些事情,所以需要阻止默認(rèn)行為。

      IE9之前的IE中,可以通過設(shè)置事件對象的returnValue屬性為false達(dá)到同樣的效果。

      function cancelHandler(event){ var event=event||window.event;//兼容IE //取消事件相關(guān)的默認(rèn)行為 if(event.preventDefault) //標(biāo)準(zhǔn)技術(shù) event.preventDefault(); if(event.returnValue) //兼容IE9之前的IE event.returnValue=false; return false; //用于處理使用對象屬性注冊的處理程序 }
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      7事件委托

      在JavaScript中,添加到頁面上的事件處理程序數(shù)量將直接關(guān)系到頁面的整體運(yùn)行性能。導(dǎo)致這一問題的原因是多方面的。首先,每個(gè)函數(shù)都是對象,都會占用內(nèi)存;內(nèi)存中的對象越多,性能就越差。其次,必須事先指定所有事件處理程序而導(dǎo)致的DOM訪問次數(shù),會延遲整個(gè)頁面的交互就緒時(shí)間。

      對“事件處理程序過多”問題的解決方案就是事件委托。事件委托利用了事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件。例如,click事件會一直冒泡到document層次。也就是說,我們可以為整個(gè)頁面指定一個(gè)onclick事件處理程序,而不必給每個(gè)可單擊的元素分別添加事件處理程序。

      在父級上定義了函數(shù),當(dāng)點(diǎn)擊目標(biāo)時(shí),會向上冒泡,到父級執(zhí)行操作。每一個(gè)子元素,都會統(tǒng)一冒泡到父級然后執(zhí)行。

      <ul id="color-list"> <li>red</li> <li>yellow</li> <li>blue</li> <li>green</li> <li>black</li> <li>white</li> </ul>
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      如果點(diǎn)擊頁面中的li元素,然后輸出li當(dāng)中的顏色,我們通常會這樣寫:

      (function(){
          var color_list = document.getElementById('color-list'); var colors = color_list.getElementsByTagName('li'); for(var i=0;i<colors.length;i++){ colors[i].addEventListener('click',showColor,false); }; function showColor(e){
              var x = e.target; alert("The color is " + x.innerHTML); }; })();
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      利用事件流的特性,我們只綁定一個(gè)事件處理函數(shù)也可以完成:

      (function(){
          var color_list = document.getElementById('color-list'); color_list.addEventListener('click',showColor,false); function showColor(e){
              var x = e.target; if(x.nodeName.toLowerCase() === 'li'){
                  alert('The color is ' + x.innerHTML); } } })();
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      事件委托還有一個(gè)好處就是添加進(jìn)來的元素也能綁定事件:

      沒有使用事件委托:

      <body> <ul id="thl"> <li>001</li> <li>002</li> <li>003</li> </ul> <button onclick="fun()">touch</button> <script> var thl= document.getElementById('thl'); var aLi = thl.getElementsByTagName('li'); for (var i = 0; i < aLi.length; i++) {
            aLi[i].onclick = fn;
          } function fn (){ console.log(this.innerHTML);
          } function fun(){ var node=document.createElement("li"); var textnode=document.createTextNode("maomaoliang");
              node.appendChild(textnode);
              document.getElementById("thl").appendChild(node);
          } </script> </body>
          
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27

      使用了事件委托:

      <script> var thl= document.getElementById('thl');
          thl.onclick = function(ev) { ev = ev || event; //兼容處理 var target = ev.target || ev.srcElement; //找到li元素 if (target.nodeName.toLowerCase() == 'li') {
                    console.log(target.innerHTML);
               }
          }; function fun(){ var node=document.createElement("li"); var textnode=document.createTextNode("maomaoliang");
              node.appendChild(textnode);
              document.getElementById("thl").appendChild(node);
          } </script>
      藍(lán)藍(lán)設(shè)計(jì)www.li-bodun.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 平面設(shè)計(jì)服務(wù)

      日歷

      鏈接

      個(gè)人資料

      存檔

      主站蜘蛛池模板: 日韩在线观看精品亚洲| 亚洲中文精品久久久久久不卡| 高清无码爆乳潮喷在线观看| 亚洲欧美另类视频| 亚洲无人区码一二三四区| 亚洲精品一区二区三区的| 国内精品久久久久精免费| 国产激情视频在线观看的| 亚洲欧美日韩精品色xxx| 亚洲va久久久噜噜噜久久狠狠| 午夜天堂精品久久久久| 久久大香香蕉国产| AV无码网站网址| 亚洲成人四虎在线播放| 无码国产精品一区二区色情男同| 久久久99无码一区| 久久人人爽人人人人片| 国产av无码专区影视| 国产欧美日韩| 久久夜夜免费视频| 国产成人做受免费视频| 国产精品ⅴ无码大片在线看| 成人午夜福利视频| 日韩人妻ol丝袜av一二区| 免费网禁国产you女网站下载| 2021国产最新无码视频| 国产99在线 | 免费| 欧美性色老妇人| 精品视频一区二区| 国产精品人成在线播放| 一本一本久久久久a久久综合激情| 18pao成人国产永久视频| 人妻av久久一区波多野结衣| 重口sm一区二区三区视频| 亚洲国产精品特色大片观看完整版| 97爱亚洲综合成人| 日韩免费无码一区二区三区| 成人啪精品视频网站午夜| 一本一本久久aa综合精品| 日韩成人午夜精品久久高潮| 国产人妻一区二区三区四区五区六|