变异观察器错误,具体取决于Chrome版本

时间:2019-02-18 16:39:38

标签: javascript jquery fullcalendar mutation-observers fullcalendar-scheduler

在FullCalendar Scheduler中,当我拖动一个div(以调整大小)时,我正在使用一个突变观察器来同步两个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 
      });
   }
}

这是一个密码笔CodePen problem

总共有4个.fc-resource-area,fullcalendar调度程序有2个元素(资源标头和资源列表),我总共有2个日历。这就是为什么我要同步两个日历资源列调整大小的原因。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您的代码中的问题:

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

解决方案:

  • 只宣布一次观察者。
  • 使用自动填充的document.getElementsByClassName代替jQuery。
  • 如果差异小于1像素,请跳过更新宽度。
  • 无需观察childList或子树,您只需拥有style属性(请参阅more tips)。

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,则在页面冻结时可以单击“源”面板中的“暂停”按钮,这将在devtools中暂停代码,以便您进行检查。