当我得到一些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”不能发生点击事件时可以使用“数据”?
答案 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对象上放置数据时,如果你创建/销毁很多这些并在旧版浏览器中运行,你必须小心谨慎地清理以避免潜在的内存泄漏或循环引用。