2012-12-06 42 views
0

我有以下幾點:jQuery的犯規調用警告框

<script language="javascript" type="text/javascript"> 
    $(document).ready(function() { 
     $.getJSON(
      "/myServer/getAllWidgets", 
      function(data) { 
       var optionsHTML = "<select id='widget-sel'>"; 
       optionsHTML += "<option selected='selected' id='default'>Select an option</option>"; 
       var len = data.length; 
       for(var i = 0; i < len; i++) { 
        optionsHTML += '<option value="' + data[i] + '">' 
         + data[i] + '</option>'; 
       } 

       optionsHTML += "</select>"; 

       $('#widget-sel-div').html(optionsHTML); 
      } 
     ); 

     $("#widget-sel").change(function() { 
      alert("Hello!"); 
     }); 
    }); 
</script> 

<div id="widget-sel-div"></div> 

所以,這個想法是,當document.ready火災,它將填充widget-sel-div一個選擇框(widget-sel),然後創建該選擇改變處理程序簡單地打印「你好!」通過警報箱到屏幕。

當我運行這個時,我沒有得到任何錯誤(Firebug根本沒有抱怨),並且select從我的AJAX調用的所有小部件中填充到/myServer/getAllWidgets問題是,更改處理程序不工作:當我選擇一個小部件時,我沒有收到警報箱。任何人都可以找到我要去的地方嗎?提前致謝。

+2

別你需要);在你的$(「#widget-sel」)後改變(function(){ alert(「Hello!」); } 我的意思是你好像沒有關閉你的change事件。 –

+0

對不起@Xeano(和其他人) - 這是我創建這個問題的一個錯字。實際的代碼是正確的,我已經更新了上面的代碼片段以反映這一點。 – IAmYourFaja

+0

這很好:)問題在下面描述,$ .getJSON是asnychroneous。 –

回答

5

在代碼運行時,DOM中不存在#widget-sel元素,因爲您將其添加到getJSON(它是異步的)回調中。當它不存在時,你不能綁定事件處理程序。

要解決這個問題,你可以委託事件處理程序越往上DOM樹(貌似可以在這種情況下使用父div)與.on()方法(jQuery的1.7+,如果您使用的是舊版本使用.delegate()代替):

$("#widget-sel-div").on("change", "#widget-sel", function() { 
    alert("Hello!"); 
}); 
+0

謝謝@James Allardice(+1) - 請在Rory的答案下看到我的評論 - 我對你有同樣的問題。再次感謝! – IAmYourFaja

+0

@HeineyBehinds - 不客氣:)是的,你對Rory的回答評論中的例子完全正確。需要注意的重要一點是,函數標識符後面沒有括號 - 您需要將* reference *傳遞給該函數,而不是它的返回值。 –

2

這是由於AJAX調用的異步特性。 change處理程序將在AJAX調用完成之前執行,因此DOM中將沒有要綁定的元素。相反,將change在AJAX調用回:

$.getJSON(
    "/myServer/getAllWidgets", 
    function(data) { 
     var optionsHTML = "<select id='widget-sel'>"; 
     optionsHTML += "<option selected='selected' id='default'>Select an option</option>"; 
     var len = data.length; 
     for(var i = 0; i < len; i++) { 
      optionsHTML += '<option value="' + data[i] + '">' + data[i] + '</option>'; 
     } 
     optionsHTML += "</select>"; 

     $('#widget-sel-div').html(optionsHTML); 
     $("#widget-sel").change(function() { 
      alert("Hello!"); 
     } 
    } 
); 

或者你也可以離開change處理它在哪裏,並委託事件監聽器這樣的靜態父元素:

$('#widget-sel-div').on('change', '#widget-sel', function() { 
     alert("Hello!"); 
}); 
+0

爲什麼這會降低投票率?這是一個非常有效的答案。 –

+0

Thanks @Rory McCrossan(+1) - 實際變更處理程序將會非常大。我可以在其他地方(document.ready之外)定義一個函數,然後從AJAX回調中調用它嗎?因此,而不是'$(「#widget-sel」)。change(function()...''具有'$(「#widget-sel」)。change(myFunc);'?如果是那樣的正確語法? – IAmYourFaja

+0

@HeineyBehinds這將工作得很好,你的語法也是正確的:) –