取决于 Chrome 版本的 mutation Observer 错误

mutation Observer bug depending on Chrome version

我在 FullCalendar Scheduler 中使用变异观察器来同步两个 div 的宽度(以调整大小)。

我使用的是 Chrome 版本:72.0.3626.109,一切正常。但是,当我尝试使用低于 72.0.36 的版本时,它会在我的应用程序中产生错误。

但是突变观察者似乎工作了一段时间......而且,它似乎在边缘上不起作用。

这是代码;也许我做错了什么:

unifyResourceAreaResize: function() {
   var target = $(".fc-resource-area");
   var observer = new MutationObserver(function(mutations) {
      target.width(mutations[0].target.offsetWidth);
   });
   for (var i = 0; i < target.length; i++) {
      observer.observe(target[i], { 
         attributes: true, 
         childList: true, 
         characterData: true 
      });
   }
}

这里是codePenCodePen problem

一共有4个.fc-resource-area,fullcalendar scheduler有2个元素(资源头和资源列表),我一共有2个日历。这就是我尝试同步两个日历资源列大小调整的原因。

感谢您的帮助。

您的代码中的问题:

  • 将相同的值写入 DOM 属性将触发观察器,使其无限循环并冻结页面。
  • [查看 codepen 上的完整代码] eventAfterAllRender 可能每次都会调用您的 unifyResourceAreaResize 函数,因此除了旧的之外还会注册一个新的突变观察者,例如,如果实际的 DOM 没有改变。

解决方案:

  • 只声明一次观察者。
  • 使用自动填充的 document.getElementsByClassName 而不是 jQuery。
  • 如果差异小于 1px,则跳过更新宽度。
  • 无需观察childList或子树,你只需要style属性(参见)。

var targets = document.getElementsByClassName("fc-resource-area");
var observer = new MutationObserver(function (mutations) {
  var width = parseFloat(mutations[0].target.style.width);
  Array.prototype.forEach.call(targets, function (el) {
    if (Math.abs(parseFloat(el.style.width) - width) >= 1) {
      el.style.width = width + 'px';
    }
  });
});

function unifyResourceAreaResize() {
  for (var i = 0; i < targets.length; i++) {
    observer.observe(targets[i], {
      attributes: true,
      attributeFilter: ['style'],
    });
  }
}

P.S。如果您在 运行 代码之前打开 devtools,您可以在页面冻结时单击 Sources 面板中的 Pause 按钮​​,这将暂停 devtools 中的代码,以便您可以检查它。