2013-05-11 86 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>"); 
    } 
相關問題