2013-05-11 88 views
0

我从外部API中提取一些数据,然后将其显示在仪表板页面中。要做到这一点,我生成的DOM元素一旦我处理的数据,例如:将事件处理程序附加到JQuery生成的DOM元素

for(var key in companies) { 
    $(document.createElement("span")) 
     .attr({ id: key }) 
     .appendTo($("#someDiv")) 
     .click(function() { 
      alert(key); 
     }); 
     $("#"+key).html("<b>" + key + "</b>: $"+companies[key]+"<br>"); 
    } 

然而,当我点击任何新生成的span元素,我得到一个警报的最后一个值在companies。例如,如果我宣布:

var companies = { 
    "Google": 3, 
    "Apple": 4 
}; 

然后点击这两个谷歌span和苹果span将提醒4。我希望的行为是点击Google span以提醒3

回答

1

您需要一个带闭合捕捉key值,因为环路将被click处理程序实际执行的时间完成。试试这个:

.click((function() { 
    return function() { 
     alert(key); 
    }; 
})()); 

或者,你可以alertid,因为这就是你把它设置为:

.click(function() { 
    alert(this.id); 
}); 
+0

为什么返回调用'alert(key)'的函数会产生与调用'alert(key)'不同的行为? – 2013-05-11 18:50:18

+0

这是一个闭包,将键的值保存在函数中,因为键的每一次循环都会改变。 – adeneo 2013-05-11 18:51:47

3

如何: -

使用事件delagtion与on()只是一次附加的事件处理程序。 (见课程添加compName)。并使用其id

请参阅委托事件处理程序参考here。如果somediv已经在DOM存在,那么你可以只使用$('#someDiv').on('click','.compName',function(){...

$(function(){ 
$(document).on('click','.compName',function(){ 
//..... 
    alert(this.id); 
//.... 
}); 
.... 
for(var key in companies) { 
    $(document.createElement("span")) 
     .attr({ id: key, 'class':'compName' }).html("<b>" + key + "</b>: $"+companies[key]+"  
     <br>").html("<b>" + key + "</b>: $"+companies[key]+"<br>"). 
     .appendTo($("#someDiv")); 

    } 
//... 
}) 
+0

没有理由使用'document'委派的事件容器 - 所有的元素都附加到'#someDiv',所以我认为这是安全的使用 – Ian 2013-05-11 18:48:45

+1

当你在下一行创建元素时,为什么要使用事件委托? – adeneo 2013-05-11 18:48:46

+0

@adeneo为什么要将事件附加到每个元素,而是可以只附加到一个父级,并授权它。 – PSL 2013-05-11 18:58:25

0

那是因为你调用该函数之前,可变密钥得到改变。你需要它周围的封闭,以防止它从外部码修改:

for(var key in companies) { 
    $(document.createElement("span")) 
     .attr({ id: key }) 
     .appendTo($("#someDiv")) 
     .click((function(privatekey) { 
      return function(){ 
       alert(privatekey); 
       }; 
     })(key)); 
     $("#"+key).html("<b>" + key + "</b>: $"+companies[key]+"<br>"); 
    } 
相关问题