解决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
相关产品推荐
相关产品推荐

