【问题标题】:Execute complete function only once in jQuery animation?在jQuery动画中只执行一次完整的功能?
【发布时间】:2012-02-20 14:10:07
【问题描述】:

我正在尝试为某些文本的字体大小设置动画:

$("p").delay(500).animate({
    "font-size": "+=50"
}, 1000, function() {
    alert("Done");
})​;

Here's a demo.

我想在为<p>s(在示例中为alert)设置动画后做一些事情,但令人惊讶的是它会为每个<p> 运行它,这不是我想要的。有没有办法让它只运行一次还是不可能?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    请注意,您也可以使用promise object

    返回一个 Promise 对象以观察某个类型的所有操作何时发生 绑定到集合,无论是否排队,都已完成。

    第一个示例 (demo):

    $("p").delay(500).animate({
        "font-size": "+=50"
    }, 1000).promise().done(function(){
        alert("done");
    });​
    

    第二个例子 (demo):

    $.when($("p").delay(500).animate({
        "font-size": "+=50"
    }, 1000)).done(function(){
        alert("done");
    });​
    

    【讨论】:

    • 其实这样好多了。 +1
    • 结果是一样的。这 2 个方法(promise 和 when)返回一个 promise 对象,用于像 done() 一样附加回调。
    【解决方案2】:
    var $p = $("p");
    var lastIndex = $p.length - 1;
    
    $p.delay(500).animate({
        "font-size": "+=50"
    }, 1000, function() {
        if ($p.index($(this)) == lastIndex) {
            alert("Done");
        }
    })
    

    Demo

    【讨论】:

    • 我喜欢这种不需要创建额外变量的索引方法。谢谢!
    • @Derek:它确实创建了两个额外的变量,顺便说一句:lastIndex$p...
    • @minitech,我把这两个直接放在function()里面,这就是原因。
    【解决方案3】:

    你可以只保留一个标志,因为它们应该同时动画:

    var done = false;
    
    $("p").delay(500).animate({
        "font-size": "+=50"
    }, 1000, function() {
        if(!done) {
            done = true;
            alert("Done");
        }
    })​;
    

    Here's a demo.

    【讨论】:

    • 我认为这在大多数情况下都可以很好地工作,而且更干净。
    【解决方案4】:

    为有问题的 P 标记指定一个 ID,然后选择该 ID,而不是页面上的每个 P 标记。喜欢这里:http://jsfiddle.net/LR8uP/1/

    或者,如果您想为每个 P-tag 设置动画但只运行一次函数,请添加一个状态变量,如下所示:http://jsfiddle.net/LR8uP/2/

    【讨论】:

    • 不,我想为所有<p>s 设置动画,但只执行一次。
    【解决方案5】:

    此代码可用作通用“倒计时”类型的函数。

    // Function that returns a function,
    // which when invoked 'count' number of times,
    // will invoke the function 'fn'
    function runOnZero (count, fn) {
        return function () {
            if (--count <= 0) {
                fn();
            }
        };
    }
    
    // Get all the <p>s
    var ps = $("p");
    
    // Do your thing after ps.length calls
    var whenAllDone = runOnZero(ps.length, function () {
       alert("Done");
    });
    
    ps.delay(500).animate({
        "font-size": "+=50"
    }, 1000, whenAllDone)​;
    

    【讨论】:

    • whenAllDone 函数为列表中的每个 &lt;p&gt; 调用一次(在每个 &lt;p&gt; 被动画化之后)。当whenAllDone 被调用时,它会递减一个计数器。当计数器达到零时,调用 real 函数。真正的函数是调用alert() 的函数。所以虽然whenAllDone 会被调用ps.length 次,但它只会调用alert() 一次,最后一次是&lt;p&gt;
    猜你喜欢
    • 1970-01-01
    • 2016-11-10
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多