如何在js中动态添加事件

时间:2011-07-11 04:24:44

标签: javascript html

当我得到一些json数据时,我想在页面中显示它们:

代码:

    function update(){

      for(far i=0;i<data.length;i++){
        var l=document.createElement("li"); 
        document.getElementById("ul_con").appendChild(l);
        l.onclick=function(){
          alert ("id:"+data[i].id);
        }

      }
}

但是,我收到错误:data [i] i未定义。

任何方式?

顺便说一句,因为我在手机上发布了这个问题,所以我不能很好地格式化代码。希望有人可以帮我一个忙。

更新:

    function update(){

      for(var i=0;i<data.length;i++){
        var l=document.createElement("li"); 
        l.tindex=i;
        document.getElementById("ul_con").appendChild(l);
        l.onclick=function(){
          alert ("id:"+data[this.tindex].id);
        }

      }
}

此代码也有效,但我想知道为什么在“i”不能发生点击事件时可以使用“数据”?

2 个答案:

答案 0 :(得分:1)

onclick事件触发时,data[]数组不在上下文中。您需要使用this代替

l.onclick=function(){
   alert ("id:"+this.id);
}

答案 1 :(得分:1)

当调用onclick函数时,它比你连接事件处理程序和数据的时间要晚得多,并且i值可能不再是你连接函数时的那些值,所以你不能依赖它在他们。实际上,i值保证不相同,因为它会因为循环的后续交互而提前。根据代码的其余部分,数据值可能有效,也可能无效。

您可以冻结它们以在事件处理程序中使用,如下所示:

function update(){
    for(far i=0;i<data.length;i++){
        var l=document.createElement("li"); 
        document.getElementById("ul_con").appendChild(l);
        l.onclick=(function(mydata, index){     // define function that gets called at assignment time
            // variables mydata and index are available here in this scope
             return function() {
                alert ("id:"+mydata[index].id);
            };
       })(data, i);   // pass data and i into the inner scope
    }
}

通过这种方式,在分配onclick处理程序时执行第一个函数(data,i)。这将评估数据和i,并通过函数闭包建立它们在内部函数中使用的值。有关说明和更多示例,请参阅this writeup。由于data是一个数组,所以你不是在这里复制它(它是通过引用传递的)所以你必须确保它的值被保留到click处理程序的时间(尽管它不会超出范围因为这个闭包保留它)。 i的值被复制到函数参数中,因此您不必担心外部循环会改变i的值。

当它看起来像这样时,它会更容易混淆和更容易理解,但是如果你研究这两个,你可以看到它们真的是一样的,第一个例子只有一个内联无名函数定义:

function processMyClick(mydata, index) {
    return function() {
        alert ("id:"+mydata[index].id);
    };
}

function update(){
    for(far i=0;i<data.length;i++){
        var l=document.createElement("li"); 
        document.getElementById("ul_con").appendChild(l);
        l.onclick=processMyClick(data, i);
    }
}

如果您需要的只是该数据结构中的一些数据,那么您可能只想将它放在DOM对象本身上:

function update(){
    for(far i=0;i<data.length;i++){
        var l=document.createElement("li"); 
        document.getElementById("ul_con").appendChild(l);
        l.myId = data[i];
        l.onclick=function() {alert(this.myId);};
    }
}

在DOM对象上放置数据时,如果你创建/销毁很多这些并在旧版浏览器中运行,你必须小心谨慎地清理以避免潜在的内存泄漏或循环引用。