简体   繁体   English

回调函数“未定义”

[英]Callback function “is not defined”

I am building a script that fetches multiple JSON feeds from Tumblr and creates HTML lists based on that data. 我正在构建一个脚本,该脚本从Tumblr获取多个JSON提要,并基于该数据创建HTML列表。 Pretty straightforward concept. 非常简单的概念。

Here's the output: http://fotis.co/tumblr/index.html 输出为: http : //fotis.co/tumblr/index.html

The script is partly working as I'm stumbling on "callback function not defined" issues. 该脚本在某种程度上可以正常工作,因为我遇到了“未定义回调函数”问题。 That happens only when I choose to use a callback function when requesting the Tumblr JSON feed. 仅当我选择在请求Tumblr JSON feed时使用回调函数时,这种情况才会发生。 By default, if you don't specify a callback function via the Tumblr API, the JSON object returned is assigned to a variable named tumblr_api_read. 默认情况下,如果您未通过Tumblr API指定回调函数,则将返回的JSON对象分配给名为tumblr_api_read的变量。 So the JSON actually returns: 因此,JSON实际上返回:

var tumblr_api_read = {the JSON object data goes here};

If I use a callback function, the JSON data is returned like this (as expected): 如果我使用回调函数,则将JSON数据返回(如下所示):

callbackFunctionName({the JSON object data goes here});

If you check out the script code here http://fotis.co/tumblr/tumblr.js : 如果您在此处查看脚本代码http://fotis.co/tumblr/tumblr.js

/* Read Tumblr */

function ready(cb) {
    /in/.test(document.readyState) ? setTimeout('ready('+cb+')', 9) : cb();
}

function getTumblrFeed(params) {
    /*
    Legend:
    start - The post offset to start from. The default is 0.
    num - The number of posts to return. The default is 20, and the maximum is 50.
    type - The type of posts to return. If unspecified or empty, all types of posts are returned. Must be one of text, quote, photo, link, chat, video, or audio.
    id - A specific post ID to return. Use instead of start, num, or type.
    filter - Alternate filter to run on the text content. Allowed values:
        text - Plain text only. No HTML.
        none - No post-processing. Output exactly what the author entered. (Note: Some authors write in Markdown, which will not be converted to HTML when this option is used.)
    tagged - Return posts with this tag in reverse-chronological order (newest first). Optionally specify chrono=1 to sort in chronological order (oldest first).
    search - Search for posts with this query.
    */
    if(params.blogurl) var blogurl = params.blogurl;
    if(params.postcount) var num = params.postcount;
    var jsonurl = document.location.protocol+ '//' +blogurl+ '/api/read/json?num=' +num;
    if(params.type) jsonurl += '&type=' + params.type;
    if(params.tagged) jsonurl += '&tagged=' + params.tagged;
    if(params.search) jsonurl += '&search=' + params.search;
    if(params.callback) jsonurl += '&callback=' + params.callback;
    var jsonfeedscript = document.createElement('script');
    jsonfeedscript.setAttribute('charset', 'utf-8');
    jsonfeedscript.setAttribute('type', 'text/javascript');
    jsonfeedscript.setAttribute('async', 'true');
    jsonfeedscript.setAttribute('src', jsonurl);
    return jsonfeedscript;
}

function renderResults(settings) {
    var tumblrObj = (settings.callback) ? settings.callback : tumblr_api_read;

    var i = 0;
    var c = document.getElementById(settings.container);

    for(i; i<tumblrObj.posts.length; i++){
        // URL
        var postUrl = tumblrObj.posts[i]['url-with-slug'];
        // Title
        if(tumblrObj.posts[i]['regular-title']){
            var postTitle = tumblrObj.posts[i]['regular-title'];
        } else if(tumblrObj.posts[i]['quote-text']){
            var postTitle = tumblrObj.posts[i]['quote-text'];
        } else if(tumblrObj.posts[i]['link-text']){
            var postTitle = tumblrObj.posts[i]['link-text'];
        } else if(tumblrObj.posts[i]['audio-caption']){
            var postTitle = tumblrObj.posts[i]['audio-caption'];
        } else if(tumblrObj.posts[i]['photo-caption']){
            var postTitle = tumblrObj.posts[i]['photo-caption'];
        } else if(tumblrObj.posts[i]['video-caption']){
            var postTitle = tumblrObj.posts[i]['video-caption'];
        } else if(tumblrObj.posts[i]['conversation-text']){
            var postTitle = tumblrObj.posts[i]['conversation-text'];
        } else {
            var postTitle = '';
        }
        // Date
        var postDate = tumblrObj.posts[i]['date']; // or: date-gmt, unix-timestamp
        // Type
        var postType = tumblrObj.posts[i]['type'];
        // Output
        var output = settings.theme.replace("{postUrl}",postUrl).replace("{postTitle}",postTitle).replace("{postDate}",postDate);
        c.innerHTML += output;
    }

    // Hide the loader
    var l = document.getElementById(settings.loader);
    c.removeChild(l);
}

function readTumblr(settings) {
    // Load JSON data
    var head = document.getElementsByTagName('head')[0];
    var jsonfeedscript = getTumblrFeed(settings);
    head.appendChild(jsonfeedscript);

    jsonfeedscript.onload = function(){
        renderResults(settings);
    }
}

You will see that I do a check if the JSON feed is invoked with a callback function (inside readTumblr()), otherwise I just use the default object "tumblr_api_read". 您将看到我进行了检查是否使用回调函数(在readTumblr()内)调用了JSON feed,否则我只使用默认对象“ tumblr_api_read”。 If no callback function is defined where the script is initialized (inside index.html) the Tumblr JSON data are properly rendered (see Containers 2 and 3 in the html output). 如果未在初始化脚本的位置(在index.html内)定义回调函数,则将正确呈现Tumblr JSON数据(请参见html输出中的容器2和3)。 If I DO define a callback function, I get something like "callbackFunctioName is not defined" and then rendering fails. 如果确实定义了回调函数,则会得到类似“未定义callbackFunctioName”的内容,然后渲染将失败。

Am I missing something here? 我在这里想念什么吗? Is it a scope issue? 这是范围问题吗? And if so, how can I bypass it? 如果是这样,我该如何绕过它?

Thanks in advance for any answers. 预先感谢您的任何答案。

EDIT 1 : Updated script code above. 编辑1 :更新了上面的脚本代码。

If you supply a callback to a JSONP API, you'll get back a JavaScript snippet that calls whatever function you supplied with the JSON data as an argument. 如果您提供对JSONP API的回调,您将获得一个JavaScript代码段,该代码段调用您随JSON数据提供的任何函数作为参数。 As you noted: 如您所述:

callbackFunctionName({the JSON object data goes here});

The JSONP/callback system all depends on your code having already defined the callbackFunctionName function, so there's something to be called. JSONP /回调系统都取决于您的代码是否已经定义了callbackFunctionName函数,因此有一些要调用的东西。 The idea is, you put your code that needs to work on the Tumblr data in that callback function. 想法是,将需要处理Tumblr数据的代码放在该回调函数中。

If you prefer working with the var tumblr_api_read way of doing things, just don't specify a callback. 如果您更喜欢使用var tumblr_api_read方式,则无需指定回调。

Otherwise, you'd basically want to move what you currently have as jsonfeedscript.onload to whatever function you're defining as the callback. 否则,您基本上希望将当前作为jsonfeedscript.onload移至您定义为回调的任何函数。 As an example, if you gave the Tumblr API a "callback" parameter of "myCallback", your code should look basically like: 例如,如果为Tumblr API提供了“ myCallback”的“ callback”参数,则代码基本上应该像这样:

function myCallback(tumblrObj) {
    // Your code that reads the JSON and inserts the HTML
}

You don't then ever need to call myCallback yourself . 这样,您就无需自己调用myCallback You just make the JSONP request by inserting the script tag, and the Tumblr API will give you back a script that calls myCallback and passes in the JSON data. 您只需通过插入script标签发出JSONP请求,Tumblr API将为您提供一个调用myCallback并传递JSON数据的脚本。

Shouldn't this line: 这行不应该:

tumblrObj = (settings.callback) ? settings.callback : tumblr_api_read

be: 是:

tumblrObj = (settings.callback) ? settings.callback() : tumblr_api_read

?

I'm not sure, it looks weird to me. 我不确定,这看起来对我来说很奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM