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

FullCalendar中Mutation Observer无法检测DOM元素删除的问题

FullCalendar中Mutation Observer无法检测DOM元素删除的问题

嘿,我仔细看了你的代码和问题描述,核心问题其实出在Mutation Observer的判断逻辑写错了,另外还有几个小细节需要调整,咱们一步步来解决:

问题1:Mutation Observer的判断条件完全错误

你代码里写了typeof e[0].removedNodes === 'array',但实际上removedNodes是NodeList对象(不是标准JavaScript数组),所以这个条件永远不会为真,直接导致后面检测元素删除的逻辑根本跑不起来。

而且直接判断e.removedNodes[0] === elem也不靠谱——被删除的节点不一定是removedNodes里的第一个,这个判断太局限了。

问题2:FullCalendar关闭popover的额外场景

当用户点击外部区域或按ESC关闭popover时,FullCalendar的执行流程和点击关闭按钮略有不同,但只要把Observer的逻辑修对,就能覆盖所有删除场景。

修复后的完整方案

1. 彻底修正observeDeletion函数

把判断逻辑改成正确的NodeList检测方式,遍历所有被删除的节点来匹配目标元素:

function observeDeletion(elem){
    var target = elem.parentNode;
    console.log('observing target:', target);
    const calPopupObserver = new MutationObserver(function (mutations) {
        mutations.forEach(mutation => {
            // 把NodeList转成数组,遍历检查是否包含目标elem
            Array.from(mutation.removedNodes).forEach(node => {
                if (node === elem) {
                    console.log('Fixing Links - 检测到popover被删除!');
                    fixLinksOnCalendar(true);
                    calPopupObserver.disconnect(); // 完成后断开监听,避免重复触发
                }
            });
        });
    });
    // 简化监听配置:只需要监听子节点变化,不需要subtree
    calPopupObserver.observe(target, { childList: true });
};

2. 可选:用FullCalendar原生事件更可靠(推荐)

其实FullCalendar V6本身提供了和popover相关的事件,比如popoverHidden,直接监听这个官方事件会比Mutation Observer更稳定,不用依赖DOM变化的监听:

// 假设你的FullCalendar实例是calendar(初始化时定义的变量)
calendar.on('popoverHidden', function() {
    fixLinksOnCalendar(true);
});

如果不想改动FullCalendar的初始化代码,只修正上面的Observer逻辑也足够解决问题。

3. 优化fixLinksOnCalendar的重复代码

你里面重复了三次几乎一样的$.each,可以合并成一次,让代码更简洁:

function fixLinksOnCalendar(repeat){
    setTimeout(function(){
        var calTextColor = settings.dark_ui == 'no' ? settings.colors[5]:settings.colors[4];
        // 合并所有需要修改的选择器,一次遍历处理
        $('.fc-more-link, a.fc-more-link, a.fc-daygrid-more-link').each(function(){
            // 通用样式先设置
            $(this).css({marginTop: '-10px', color: calTextColor, fontWeight: 600});
            // 移动端特殊样式
            if ($(window).width() < 521) {
                const newText = '+'+parseInt($(this).text(), 10);
                $(this).text(newText).css({
                    color: 'white', 
                    backgroundColor: settings.colors[5], 
                    padding: '3px 6px', 
                    borderRadius: '10px', 
                    marginLeft: '12px'
                });
            }
        });
        if (repeat) fixLinksOnCalendar(false);
    },300);
}

测试验证

修改完observeDeletion后,再测试点击外部区域或按ESC关闭popover,你应该能在控制台看到Fixing Links - 检测到popover被删除!的日志,同时fixLinksOnCalendar会被正确调用。


备注:内容来源于stack exchange,提问作者Jason Overhulser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:59:50