2010-06-16 3 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'이 호출됩니다. 데이터를 사용할 수는 있지만 '추천'을 선택하면 this.keywords 배열 또는 this.suggest_url을 사용할 수 없습니다. 나는 'JSONcallback'과 'Suggest'가 다른 문맥에서 호출되기 때문에 이것이라고 생각한다.

어떻게하면됩니까? 직접 프로토 타입에 함수를 호출 할 때

답변

0

, 그것은 autosuggest.prototype.JSONCallback를 호출하지만 기능은 this.suggest()를 호출 할 수 있으며, JSONP 호출이 반환 그러므로 때, this에 대한 컨텍스트가 없습니다.

대신에, 나는 래퍼 함수 만드는 게 좋을 것 :

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

+0

당신이 필요로하는 각각의 객체에 대한 전역 변수를 생성하고 나서 그들 자신을 참조 할 수 있도록 이름을 알려주는 것보다는 부족합니다 (예 :'var as1 = new autosuggest(); as1.name = 'as1';' 지금 당장 생각해보십시오. 아마도 당신은 AS를 영구적으로 유지할 필요가 없도록 다시 설계 할 수 있습니까? – nickf