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

解决MutationObserver监听select2位置时的循环调用与卡顿问题

这问题我之前也碰到过!核心原因就是你在MutationObserver的回调里修改元素样式的操作,又会触发新的Mutation事件,直接导致了无限循环——浏览器一直在处理回调、触发事件、再处理回调,内存自然就爆了,浏览器也冻住了。

给你几个靠谱的解决思路,亲测有效:

方法一:修改时暂时断开Observer

最直接的方式就是在修改样式前先断开观察,改完之后再重新连接。这样就不会因为我们自己的修改触发新的回调了:

/** Intercept changes in select2-drop positioning **/
// 兼容标准MutationObserver和WebKit版本
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var targetElement = document.querySelector('.select2-drop-active');

var observer = new MutationObserver(function(mutations) {
  // 先断开观察,避免修改样式触发新的Mutation
  observer.disconnect();
  
  mutations.forEach(function(mutation) {
    // 只处理style属性的变化,减少无效操作
    if (mutation.attributeName === 'style') {
      console.log("Override existent new found top value with -> " + newHeight);
      $(".select2-drop-active").css({'top': newHeight + "px"});
    }
  });
  
  // 重新连接观察,监听后续的样式变化
  observer.observe(targetElement, {
    attributes: true,
    attributeFilter: ['style'] // 只监听style属性,缩小监听范围
  });
});

// 初始化观察配置
observer.observe(targetElement, {
  attributes: true,
  attributeFilter: ['style']
});

方法二:判断目标值,避免重复修改

另一种思路是在修改前先检查当前的top值是不是已经等于我们想要的newHeight,如果已经一致就不做修改,这样就不会触发额外的Mutation事件:

/** Intercept changes in select2-drop positioning **/
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var targetElement = document.querySelector('.select2-drop-active');

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (mutation.attributeName === 'style') {
      var $drop = $(".select2-drop-active");
      var currentTop = parseInt($drop.css('top'), 10);
      // 只有当前值和目标值不一致时才修改
      if (currentTop !== newHeight) {
        console.log("Override existent new found top value with -> " + newHeight);
        $drop.css({'top': newHeight + "px"});
      }
    }
  });
});

observer.observe(targetElement, {
  attributes: true,
  attributeFilter: ['style']
});

额外优化建议

  • 尽量缩小监听范围:用attributeFilter指定只监听style属性,不要监听所有属性变化,能减少Observer的触发次数,提升性能。
  • 兼容标准API:不要只依赖window.WebKitMutationObserver,加上标准的window.MutationObserver兼容更多浏览器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:15:49