是否可以存储javascript函数调用并在设置某个变量时执行它?

时间:2013-11-13 06:53:33

标签: javascript jquery facebook-javascript-sdk

我想在按钮上附加一个onclick事件处理程序。但是如果没有设置js变量,我不希望它被调用,而是应该存储函数调用,然后在我想要的时候执行。 有可能做这样的事吗?

编辑: 更多说明:

所以基本上因为sdk还没有加载,所以仍然应该调用onclick事件处理程序,但调用不会被执行,而是存储在某个地方(在队列中)。然后在不同的代码片段中,我将检查sdk是否已加载,一旦加载,我将检查队列中是否有任何待处理的调用并执行它们。这显然不会锁定浏览器。

PS:基本上我正在使用他们的JS SDK将facebook登录集成到我的webapp中。因此,FB.login函数仅在SDK加载时才有效,但我不想拒绝用户单击登录按钮。因此,如果SDK尚未加载,则会存储调用,然后我可以在加载SDK后手动执行它。

4 个答案:

答案 0 :(得分:0)

尝试这样的事情 -

if (!FB.login) {
  // fastest in my testing.
  var fileref = document.createElement('script');
  // Some prefer "application/javascript".
  fileref.setAttribute("type", "text/javascript");
  fileref.setAttribute("src", **WHERE_TO_GET_IT**);
  if (typeof fileref!="undefined") {
    $("head").append(fileref);
  }
}

或者你走向另一个方向,只在SDK准备就绪时显示登录按钮(因为在此之前他们无法使用FB API登录)。

答案 1 :(得分:0)

也许这样的事情就足够了?

function onClickHandler(callback)
{
    // Initialize queue array on the first usage
    if (!this.queue)
        this.queue = [];

    //checking blah variable
    if (typeof(blah) == "undefined")
    {
        //blah doesn't exit, store callback in queue
        if (callback)
            this.queue.push(callback)
    }
    else
    {
        //execute all stored callback functions first
        if (this.queue.length)
        {
            this.queue.slice().forEach(function(callback) callback());
            this.queue.length = 0;
        }

        if (callback)
            callback()
    }
}

(function loop()
{
    if (typeof(blah) == "undefined")
        setTimeout(loop, 100);
    else
    {
        /*
            blah variable exists
            execute all stored (if any) callback functions
        */
        onClickHandler();
    }
})()

它的作用基本上是创建一个循环并检查 blah 变量,它继续检查直到该变量可用。 这很难看,但很有效。

答案 2 :(得分:0)

我根据你的解释使用jQuery .queue()尝试了一些东西,但这样,点击处理程序将在加载SDK后多次触发。这真的是你想要的吗?

var loaded = false;

$('button').click(function handler() {
    if (!loaded) {
        $(this).queue('demo', jQuery.proxy.apply(
            jQuery, [handler, this].concat(arguments)
        ));
        return;
    }
    // do something when loaded === true
});

setTimeout(function () {
    var button, queue;
    loaded = true;
    button = $('button');
    queue = button.queue('demo');
    while (queue.length) { 
        button.dequeue('demo');
    }
}, 3000);

以下是演示:http://jsfiddle.net/wared/PKTus/

答案 3 :(得分:0)

单一触发器的另一个建议:

var loaded = false, clicked = false;

$('button').one('click', function handler() {
    if (clicked = !loaded) {
        $(this).one('click', handler);
        return;
    }
    // do something when loaded === true
});

setTimeout(function () {
    loaded = true;
    if (clicked) $('button').trigger('click');
}, 3000);

现场演示:http://jsfiddle.net/wared/DH6DU/