JSONP context problem
I'm using a javascript autocomplete () in a greasemonkey script. On itself it works correctly but I wan't to add JSONP because I want the data from another domain. The code (snippet):
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);
I removed not relevant code. Now when 'preSuggest' is called, it add a script to the header and circumvent the crossdomain problem. Now when the data is received back 'JSONcallback' is called. I can use the data, but when 'Suggest' is I can't use the this.keywords array or this.suggest_url. I think this is because 'JSONcallback' and 'Suggest' are called in a different context.
How can I get this working?
When you call a function on the prototype directly, there is no context for this
, therefore when the JSONP call is returned, it is calling autosuggest.prototype.JSONCallback
but that function can't call this.suggest()
.
Instead, I'd suggest creating a wrapper function:
function JSONCallback(data) {
var as = new autosuggest();
as.keywords = data;
as.suggest();
}
or, create a single global autosuggest
object and use that as the callback:
var globalAS = new autosuggest("http://example/?q=");
// inside the CreateJSONPRequest function, change this line:
newScript.src = url +'&callback=globalAS.JSONCallback';
精彩评论