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

如何在jQuery UI Droppable放置动画完成后触发事件

问题原因
  1. 你之前使用$.when的方式错误:$.when接收的是Deferred异步对象,你直接传入普通函数时,它会立即完成resolve,不会等待内部逻辑执行,所以更新逻辑还是提前触发。
  2. drop事件触发时,拖拽的内置动画、元素归属切换的流程还未完全结束,此时直接调用总额计算方法,拿到的还是元素未完全移入新列的DOM状态。
解决方案

推荐使用以下两个方案,优先级从高到低:

方案1:利用draggable的stop事件触发更新(最稳妥)

jQuery UI的stop是拖拽全流程的最后一个回调,会等所有动画、元素移动、状态切换完全结束后触发,只需新增一个标识位标记是否成功完成drop即可:

dragUserInTable = function() {
    if (!$('.item').length) return;
    let isDropSuccess = false; // 新增drop成功标识

    console.log("ok about to set up draggable and droppable");

    $(".item").draggable({
        addClasses: false,
        containment: '.workflows__table',
        cursor: "drabbing",
        snap: ".workflows__board-body",
        snapMode: "inner",
        revert: "invalid",
        helper: "clone",
        snapTolerance: 50,
        zIndex: 10,
        drag: ({ target }, elem) => {
            console.log('drag for '+target+ ' ' +elem);
            $(target).addClass('item--drag');
            $(elem.helper[0]).addClass('item--dragging');
            $(target).parents('.workflows__board-body').removeClass('ui-droppable-hover');
        },
        stop: ({ target }, elem) => {
            console.log('stop for '+target+ ' ' +elem);
            $(target).removeClass('item--drag');
            $(elem.helper[0]).removeClass('item--dragging');
            $(target).removeClass('item--lost');
            // 拖拽完全结束后,判断是成功drop则更新总额
            if (isDropSuccess) {
                valueUsersAndTotalValue();
                isDropSuccess = false; // 重置标识
            }
        }
    });

    $('.workflows__board-body').droppable({
        accept: '.item',
        tolerance: "intersect",
        drop: ({ target }, elem) => {
            console.log('drop for '+target+ ' ' +elem);
            $(target).find('.workflows__users').append(elem.draggable[0]);
            $(elem.draggable[0]).removeClass('item--drag');
            $(target).find('.item--lost').removeClass('item--lost');
            // 标记drop成功,待stop事件触发后再执行更新
            isDropSuccess = true;
        },
        over: ({ target }) => {
            console.log('over for '+target);
            $(target).parents('.workflows__table').find('.item--drag').addClass('item--lost').removeClass('item--drag');
        }
    });
};

方案2:正确使用$.when等待动画完成

如果你的元素有自定义CSS过渡动画,可通过jQuery对象的promise()方法等待所有动画执行完成后再触发更新:

drop: ({ target }, elem) => {
    console.log('drop for '+target+ ' ' +elem);
    $(target).find('.workflows__users').append(elem.draggable[0]);
    $(elem.draggable[0]).removeClass('item--drag');
    $(target).find('.item--lost').removeClass('item--lost');

    // 等待拖拽元素、目标容器、拖拽辅助层的所有动画完成
    $.when(
        $(elem.draggable[0]).promise(),
        $(target).promise(),
        $(elem.helper).promise()
    ).done(function() {
        valueUsersAndTotalValue();
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:06:01