Javascript将事件添加到循环中新创建的元素

时间:2014-02-18 13:26:06

标签: javascript javascript-events

我有一个循环,它创建Html链接并在同一循环中为它们分配点击事件。 click事件似乎仅适用于循环创建的最后一个元素。

<div id="list">
</div>

<script type="text/javascript">

    users = { 
        1 : { id : 1 },
        2 : { id : 2 },
        3 : { id : 3 },
        4 : { id : 4 }              
    };

    for (var index in users) {

        var user = users[index];
        document.getElementById("list").innerHTML += '<a href="" id="user-' + user.id + '">' + user.id + '</a>';

         var element = document.querySelector("#user-" + user.id);
         console.log(element);

         element.addEventListener("click", function(event){
             console.log(this);
             event.preventDefault();
         });

    }
</script>

此处只有最后一个链接可点击。但是,如果已创建链接,则所有事件侦听器都将起作用。

<div id="list">
   <a href="#" id="user-1">1</a>        
   <a href="#" id="user-2">2</a>        
   <a href="#" id="user-3">3</a>        
   <a href="#" id="user-4">4</a> 
</div>


<script type="text/javascript">

    users = { 
        1 : { id : 1 },
        2 : { id : 2 },
        3 : { id : 3 },
        4 : { id : 4 }              
    };

    for (var index in users) {

         var user = users[index];
         var element = document.querySelector("#user-" + user.id);
         console.log(element);

         element.addEventListener("click", function(event){
             console.log(this);
             event.preventDefault();
         });

    }
</script>

这似乎没有任何问题。有没有确保在创作时将元素附加到元素上?

注意:我不想为此使用JS框架。 我知道这可以使用JQuery轻松完成。

$( "body" ).on('click', "#user-" + user.id ,function(){});

注意: 我发布的代码是我动态创建的简单代码,用于说明问题。我正在使用返回字符串的模板引擎,这就是我使用

的原因
document.getElementById("list").innerHTML += '<a href="" id="user-' + user.id + '">' + user.id + '</a>';

3 个答案:

答案 0 :(得分:1)

您的问题出现在.innerHTML中,它会在每次迭代时中断DOM,这意味着先前添加的事件将被清除,并且您只将侦听器附加到最后一个元素。您可以使用DOM API来创建和附加这些元素,一切都会正常工作:jsfiddle.net/HtxZb

但是,我会建议使用事件委托。没有jQuery,您可以像这样实现它:

document.getElementById('list')
    .addEventListener('click', function(event){ 
        var elem = event.target;
        console.log( elem );
        if( elem.nodeName.toLowerCase() === "a" ){ // a link was clicked
            /* do something with link
               for example 
                switch( elem.id ){
                }
            */
            event.preventDefault();
        }
    });

答案 1 :(得分:0)

this fiddle处尝试以下内容:

<div id="list">
</div>

users = { 1 : { id : 1 },
    2 : { id : 2 },
    3 : { id : 3 },
    4 : { id : 4 } };

for (var index in users) {

    var user = users[index];

    var element = document.createElement("a");
    element.id = "user-" + user.id;
    element.innerHTML = "user-" + user.id;

    document.getElementById("list").appendChild(element);
    console.log(element);

    element.onclick = function(event){
        console.log(this);
        event.preventDefault();
    };
}

答案 2 :(得分:0)

最好在追加到DOM元素之前附加onclick处理程序。 这应该工作

<script type="text/javascript">

users = { 
    1 : { id : 1 },
    2 : { id : 2 },
    3 : { id : 3 },
    4 : { id : 4 }              
};

for (var index in users) {

    var user = users[index];
    var a = document.createElement("a");
    a.href='#';
    a.id = "user-" + user.id ;
    a.onclick = function(event){
         console.log(this);
         event.preventDefault();
     }
    a.innerHTML = user.id;
    document.getElementById("list").appendChild(a);

}
</script>