2012-01-01 36 views
2

我與這個掙扎了一天,現在,兜兜和幫助將:-)
JS的Ajax的onreadystatechange沒有定義,儘管對象存在

摘要
異步調用的AJAX CGI與不勝感激解析器和fqdn變量,以便返回一個dns分辨率。 (返回挖@resolver $ FQDN的輸出)

問題
在Firebug我可以看到,GET請求是被異步解僱,並預期到瀏覽器的響應。但是我不能把正確的div響應文檔中的onreadystatechange如不承認的對象。

旁註
除了事實上,我通過對象的數組迭代看來,他們都當迭代之間的延遲被放置在瞬間甚至被解僱。

下面是我的意見代碼
由於解析器是一個數組,我創建了一個xmlhttprequest對象的數組。

function resolve() { 
    var numofres = 6; 
    var arr = new Array; 
    arr[0] = "192.168.1.11"; 
    arr[1] = "8.8.8.8"; 
    arr[2] = "8.8.4.4"; 
    arr[3] = "159.134.0.1"; 
    arr[4] = "159.134.0.2"; 
    var len = arr.length; 
    var ax = new Array(); //creating ax as an array 
    for (var i=0; i<=len; i++) { //iterating through the length of resolvers array 
     ax[i] = new XMLHttpRequest(); //assigning to each item in array new object 
     //alert(ax[i]); // shows that object exists 
     ax[i].onreadystatechange = function(){ 
       /*=== 
       problem is above - firebug will show: 
       **Uncaught TypeError: Cannot read property 'readyState' of undefined** 
       **ax.(anonymous function).onreadystatechangehello.cgi:30** 
       oddly it will still populate divs inner html with 'loading +1 ' 
       albeit regardless of readystate code (can be 4 or anything else) 
       It perplexes me why i is thought as a function? 
       =====*/ 
       // alert(i); //if this is enabled I will see readyState==4 populated correctly 
       if (ax[i].readyState != 4) { 
        document.getElementById('return_table_'+i).innerHTML="loading "+i; 
       } 
       if(ax[i].readyState == 4){ 
        // get data from the server response 
        var response_ready=ax[i].responseText; 
        document.getElementById('return_table_'+i).innerHTML = response_ready; 
       } 
     } 
     ax[i].open("GET","av.pl?resolver=" + arr[i] +"&fqdn=google.com",true); //works 
     ax[i].send(null); //works 
     } 

} 

回答

2

你的問題是一個非常普遍的問題。在JavaScript中,變量的範圍在功能級別,而不是在塊語句級別。因此,當您通過與變量「i」,即循環遍歷每個功能您在循環創建相同的「我」。因此,當函數實際上稱爲,「我」會是什麼在循環—結束,這就是超越了數組的結束點的值!

爲避免此問題,您需要在函數中創建另一個函數。一個乾淨的方式做到這一點是有一個單獨的本地函數:

function makeReadyStateHandler(i) { 
    return function() { 
      if (ax[i].readyState != 4) { 
       document.getElementById('return_table_'+i).innerHTML="loading "+i; 
      } 
      if(ax[i].readyState == 4){ 
       // get data from the server response 
       var response_ready=ax[i].responseText; 
       document.getElementById('return_table_'+i).innerHTML = response_ready; 
      } 
    }; 
} 

然後,只需調用從環路功能:

 ax[i].onreadystatechange = makeReadyStateHandler(i); 

通過使用這樣的一個單獨的函數,你保證每一個處理器函數將擁有自己的「i」副本,該副本被凍結在循環中的正確位置。該函數將返回一個新創建的函數作爲其結果,你會爲事件處理程序使用。

+0

我的先生!我非常感謝你爲我的問題提供了詳細和完整的答案。疑問圈壞了,函數的工作現在預期讓我更快樂,更聰明的人:-) – osse 2012-01-01 17:07:06

相關問題