2015-10-20 13 views
0

你好,我試過這段代碼:的Javascript:中的addEventListener使用數量的IDS循環

<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="utf-8" /> 
     <link rel="stylesheet" href="style.css" /> 
    </head> 

    <body> 
     <div id="elementbox"></div> 

     </div> 
     <script> 
      var se 
      for (var i=1; i<20; i++) { 
       document.getElementById('elementbox').innerHTML += 
        "<div id ="+i.toString()+" ><p>E</p><p>HTMLnb</p><p>"+i+"</p></div>"; 
       alert(document.getElementById(i.toString()).id); 
       se = document.getElementById(i.toString()); 
       se.addEventListener('click', function() { 
        alert("you clicked"); 
       }, false); 
      } 
     </script> 
    </body> 
</html> 

我試圖用「報警」 s到調試,但我仍然無法找出錯誤。謝謝。

+0

爲什麼你認爲這是一個 「錯誤」? –

回答

1

當您分配給innerHTML時,瀏覽器必須重建該父元素內的所有DOM元素。因此,在第20次迭代中,所有先前的div元素都會使事件處理程序不再存在於DOM中,因此可能永遠不會響應click事件。

var container = document.getElementById("elementbox"); 
 
for (var i = 0; i < 20; i++) { 
 
    var div = document.createElement("div"); 
 
    div.id = i; 
 
    div.textContent = "Click Me (" + i + ")"; 
 
    (function(i) { 
 
     div.addEventListener("click", function() { 
 
      alert("clicked " + i); 
 
     }) 
 
    })(i); 
 
    container.appendChild(div); 
 
}
<div id="elementbox"></div>

只是爲了進一步解釋(因爲我敢肯定,你會遇到這樣的不久),此位:

(function(i) { 
    div.addEventListener("click", function() { 
     alert("clicked " + i); 
    }); 
})(i); 

是在JavaScript中的變量範圍的事。如果沒有這個內部函數,回調會訪問的for循環正在訪問(和更改)的確切副本......這意味着每次點擊總是會得到「點擊20」,因爲這是i等於循環已完成運行。

因此,此代碼創建一個匿名函數並立即調用它,傳遞當前狀態i。內部函數中的i是一個新的作用域,因此當事件處理程序回調最終觸發(通過單擊div)時不會更改。因此,當您啓動事件處理程序時,它將訪問爲您附加的每個處理程序創建的i副本。

希望這是有道理的。

+0

警報不在片段中觸發。不知道這是否是故意的。 – santon

+0

他們應該是;點擊它說「點擊我」:)。等一下,它似乎不適用於Chrome(適用於FF和IE)。由於模態窗口的安全性,在控制檯中出現錯誤,因爲'alert'不被允許。嗯,這是一個jsfiddle:http://jsfiddle.net/nauzilus/e3pp1d1b/ –

0

除了逐個添加eventlisteners和div,您應該嘗試一次以避免DOM性能損失。在DOM上創建元素後,您可以添加所有事件處理程序。我沒有優化此代碼,因此運行第二個循環來註冊所有事件處理程序。

要記住循環變量,您將不得不使用IIFE或立即調用函數表達式,該表達式會引入循環計數器併爲您的事件處理程序可以訪問的變量(閉包)創建專用作用域。

警報不在此片段中觸發,所以我添加了一個span標記來捕獲每次單擊的消息。

window.onload = function() { 
 

 
    var html = ""; 
 
    for (var i = 1; i < 20; i++) { 
 
    html += "<div><a href='#' id ='" + i.toString() + "'>E HTMLnb " + i + "</a></div>"; 
 
    } 
 
    document.getElementById('elementbox').innerHTML = html; 
 

 
    for (var i = 1; i < 20; i++) { 
 
    document.getElementById(i.toString()).addEventListener('click', (function(loopCnt) { 
 
     return function() { 
 
      document.getElementById("message").innerHTML += "<br>you clicked " + loopCnt; 
 
     }; 
 
    }(i)), false); 
 
    } 
 
};
<div id="elementbox"></div> 
 

 
<span id="message"></span>