【问题标题】:How can I prevent a callback from firing multiple times?如何防止回调多次触发?
【发布时间】:2024-01-08 23:52:01
【问题描述】:

我在这里看到了一些与此相关的问题(包括使用何时/承诺解决方案),但它们似乎不起作用。基本上我一次为多个元素设置动画,并在回调中调用一个函数,但该函数被多次调用 - 对于每个被动画的元素......这是我的代码:

OBJCollection.css({
    'width': '0em',
    'height': '0em'
}).animate({
    'width': Screens.ImageW / 16 + 'em',
    'height': Screens.ImageH / 16 + 'em'
}, {
    duration: Screens.currentImageParent.data('LightboxFadeSpeedIn'),
    queue: false,
    step: function (now, fx) {
        componentScaler();
    },
    complete: function () {
        $Content.show('fade', Screens.currentImageParent.data('ContentFadeSpeedIn'));
        //calling function here
    }
});

我尝试过:

if (!OBJCollection.is(':animated')) { ... call function }

这没有用。我也尝试过使用 when 的解决方案,但这似乎会引发我的函数调用(它根据 OBJCollection 的最终动画大小定位其他元素)。我不确定(因为这是我第一次使用 when/promise),但它是否在第一个项目完成动画并忽略所有其他项目后触发回调一次?看起来这就是它正在做的事情,但我正在寻找一种解决方案,当所有项目都完成动画时触发回调......

有什么想法吗?

【问题讨论】:

    标签: javascript jquery callback jquery-animate


    【解决方案1】:

    使用一个承诺对象。

    OBJCollection.css({
        'width': '0em',
        'height': '0em'
    }).animate({
        'width': Screens.ImageW / 16 + 'em',
        'height': Screens.ImageH / 16 + 'em'
    }, {
        duration: Screens.currentImageParent.data('LightboxFadeSpeedIn'),
        queue: false,
        step: function(now, fx) {
            componentScaler();
        }
    }).promise().done(function() {
        $Content.show('fade', Screens.currentImageParent.data('ContentFadeSpeedIn'));
        //calling function here
    });​
    

    【讨论】:

    • 这行得通,不会抛出任何错误,但就像我说的,我试了一下,看起来它在第一个动画完成后触发回调,然后忽略其余的.. . 我正在寻找一种方法来等到所有动画都完成。
    • 什么是“其余的”? Promise 对象将等待,直到所选元素上的所有现有动画都完成。
    • 我正在通读 DOC 以获得承诺(抱歉之前从未使用过它),它应该在集合中的所有动画都完成后运行该功能......所以我不完全是确定为什么它在我的情况下似乎无法正常工作。
    • 什么是componentScaler()?它在做动画吗?
    • 它根据 OBJCollection 的位置/尺寸来定位附加元素。我认为 promise 有效,但我需要重写一些其他代码,我会将其标记为答案。谢谢! :)