【问题标题】:JSONP context problemJSONP 上下文问题
【发布时间】:2010-10-05 05:37:24
【问题描述】:

我在greasemonkey 脚本中使用了javascript 自动完成()。它本身可以正常工作,但我不想添加 JSONP,因为我想要来自另一个域的数据。 代码(sn-p):

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”在不同的上下文中被调用。

我怎样才能让它工作?

【问题讨论】:

    标签: javascript jsonp


    【解决方案1】:

    当你直接调用原型上的函数时,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';
    

    【讨论】:

    • 您的第一个示例创建了一个新的自动建议对象,但我想保留我的“旧”对象以存储其他数据,例如Suggest_url。我正在为页面上的每个输入元素创建多个自动建议对象。还有其他解决办法吗?
    • 没有为您需要的每个对象创建全局变量,然后让他们知道一个名称以便他们可以引用自己(例如:var as1 = new autosuggest(); as1.name = 'as1'; 那么我现在真的想不出任何东西。也许可以您重新架构以便不需要持久的 AS 对象?
    猜你喜欢
    • 1970-01-01
    • 2013-09-12
    • 2021-05-09
    • 2011-10-14
    • 2013-04-29
    • 2012-08-14
    • 2013-04-25
    • 1970-01-01
    • 2011-12-01
    相关资源
    最近更新 更多