You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击网格元素时嵌套setTimeout被其他点击中断的问题求助

问题根源:全局变量被覆盖

你代码里的elem = $(this);没有用let/const/var声明,导致elem变成了全局变量。每次点击新的.grid-item时,这个全局的elem都会被替换成当前点击的元素对象。

当你快速点击第二个元素时,第一个元素的第一个setTimeout回调还没执行,全局elem已经被换成第二个元素了。等第一个setTimeout触发时,complete_item_anim(elem)操作的是第二个元素,而第一个元素的后续动画逻辑就彻底丢失了——因为后续嵌套的setTimeout里的elem也指向了第二个元素,自然不会再处理第一个元素。

修复方案

把elem改成局部变量,用const(或let)声明,确保每个点击事件的回调都持有自己独立的元素引用:

function complete_item_anim(obj) {
    obj.find('.orderitemprogressbar_text_status').fadeOut(200);
    obj.find('.orderitemprogressbar_text_done').fadeIn(200);
    obj.find('.order_item_box').addClass('completed');
}

$('.grid-item').click(function(event) {
    // 用const声明局部变量,避免全局污染
    const elem = $(this);
    elem.find('.oitpb_percent').text('100%');
    elem.find('.oitpb_time').text('0m');
    elem.find('.oitpb_time_group').css('max-width', 0);
    elem.find('.orderitemprogressbar_green').css('width', '100%');

    setTimeout(function() {
        complete_item_anim(elem);
        setTimeout(function() {
            elem.find('.order_item_box').addClass('removed');
            setTimeout(function() {
                elem.remove();
            }, 500);
        }, 600);
    }, 600);
});
额外优化建议

如果需要支持用户中途取消某个元素的动画(比如重复点击同一个元素),可以给每个元素绑定自己的timeout ID,点击时先清除之前的timeout:

function complete_item_anim(obj) {
    obj.find('.orderitemprogressbar_text_status').fadeOut(200);
    obj.find('.orderitemprogressbar_text_done').fadeIn(200);
    obj.find('.order_item_box').addClass('completed');
}

$('.grid-item').click(function(event) {
    const elem = $(this);
    // 清除当前元素已有的所有timeout
    if (elem.data('timeouts')) {
        elem.data('timeouts').forEach(id => clearTimeout(id));
    }

    elem.find('.oitpb_percent').text('100%');
    elem.find('.oitpb_time').text('0m');
    elem.find('.oitpb_time_group').css('max-width', 0);
    elem.find('.orderitemprogressbar_green').css('width', '100%');

    const timeouts = [];
    const timeout1 = setTimeout(function() {
        complete_item_anim(elem);
        const timeout2 = setTimeout(function() {
            elem.find('.order_item_box').addClass('removed');
            const timeout3 = setTimeout(function() {
                elem.remove();
            }, 500);
            timeouts.push(timeout3);
        }, 600);
        timeouts.push(timeout2);
    }, 600);
    timeouts.push(timeout1);
    // 把timeout ID存在元素的data里
    elem.data('timeouts', timeouts);
});

这样用户重复点击同一个元素时,会先终止之前的动画流程,重新开始新的,体验更友好。

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:57:03