2010-06-16 61 views
0

我在一個greasemonkey腳本中使用javascript autocomplete()。本身它工作正常,但我不想添加JSONP,因爲我想從另一個域的數據。 代碼(片段):JSONP上下文問題

function autosuggest(url) 
{ 
    this.suggest_url = url; 
    this.keywords = []; 

    return this.construct(); 
}; 

autosuggest.prototype = 
{ 
    construct: function() 
    { 
     return this; 
    }, 

    preSuggest: function() 
    { 
     this.CreateJSONPRequest(this.suggest_url + "foo"); 
    }, 

    CreateJSONPRequest: function(url) 
    { 
     var headID = document.getElementsByTagName("head")[0];   
     var newScript = document.createElement('script'); 
     newScript.type = 'text/javascript'; 
     newScript.src = url +'&callback=autosuggest.prototype.JSONCallback'; 
     //newScript.async = true; 
     newScript.onload = newScript.onreadystatechange = function() {   
      if (newScript.readyState === "loaded" || newScript.readyState === "complete") 
      { 
       //remove it again 
       newScript.onload = newScript.onreadystatechange = null; 
       if (newScript && newScript.parentNode) { 
        newScript.parentNode.removeChild(newScript); 
       } 
      } 
     } 

     headID.appendChild(newScript); 
    }, 

    JSONCallback: function(data) 
    { 
     if(data) 
     { 
      this.keywords = data; 
      this.suggest(); 
     } 
    }, 

    suggest: function() 
    { 
     //use this.keywords 
    } 
}; 

//Add suggestion box to textboxes 
window.opera.addEventListener('AfterEvent.load', function (e) 
{ 
    var textboxes = document.getElementsByTagName('input'); 
    for (var i = 0; i < textboxes.length; i++) 
    { 
     var tb = textboxes[i]; 
     if (tb.type == 'text') 
     {  
      if (tb.autocomplete == undefined || 
       tb.autocomplete == '' || 
       tb.autocomplete == 'on') 
      { 
       //we handle autosuggestion 
       tb.setAttribute('autocomplete','off');  
       var obj1 = new autosuggest("http://test.php?q=");    
      } 
     } 
    } 
}, false); 

我去掉不相關的代碼。現在,當調用'preSuggest'時,它會向頭添加一個腳本並繞過跨域問題。現在,當接收到數據時,會調用'JSONcallback'。我可以使用這些數據,但是當'Suggest'是我不能使用this.keywords數組或this.suggest_url。我認爲這是因爲'JSONcallback'和'Suggest'是在不同的上下文中調用的。

我該如何得到這個工作?

回答

0

當您直接在原型上調用函數時,this沒有上下文,因此當返回JSONP調用時,它調用autosuggest.prototype.JSONCallback,但該函數不能調用this.suggest()

相反,我建議創建一個包裝函數:

function JSONCallback(data) { 
    var as = new autosuggest(); 
    as.keywords = data; 
    as.suggest(); 
} 

,或者創建一個單一的全球autosuggest對象,並使用它作爲回調:

var globalAS = new autosuggest("http://example/?q="); 

// inside the CreateJSONPRequest function, change this line: 
newScript.src = url +'&callback=globalAS.JSONCallback'; 
+0

你的第一個示例創建一個新的自動提示對象,但我想保留其他數據(如suggest_url)的「舊」對象。我爲頁面上的每個輸入元素創建了多個自動建議對象。還有其他解決方案嗎? – RvdK 2010-06-16 09:43:29

+0

沒有爲你需要的每個對象創建全局變量,然後讓他們知道一個名字,以便他們可以引用自己(例如:var as1 = new autosuggest(); as1.name ='as1';'然後我不能真的想想現在的任何事情,也許你可以重新設計架構,以便不需要持久的AS對象? – nickf 2010-06-16 13:15:40