ResizeObserver的错误

为什么会存在ResizeObserver错误

ResizeObserver loop completed with undelivered notifications.

ResizeObserver用于监听元素content size和border size的变化。但是元素的变化和监听可能会导致循环触发,例如有元素A,监听元素A尺寸变化后将元素A的宽度加10px,如果没有特殊处理,那么线程将一直被占用无法进行其他任务,因为:A 宽度加10,监听到元素A尺寸变化后,A 宽度加10,监听到元素A尺寸变化后,A 宽度加10...就这么一直下去。

所以浏览器引入了策略,触发ResizeObserver事件后,所有回调会在这一帧绘制到屏幕前执行,在遍历执行所有回调函数时对于触发回调的目标元素和其父元素的ResizeObserver的监听回调会推迟到下一帧执行,同时会在控制台抛出错误ResizeObserver loop completed with undelivered notifications.

也就是说:

  1. A > B 当A宽度增加时,B宽度同步增加同时监听A元素和B元素的变化。那么当A元素变化时监听B元素尺寸变化的回调会同步执行,并且A元素变化的监听函数会推迟到下一帧执行,并且控制台报错,因为有未执行的回调。

  2. Contaienr > A > B 当A宽度增加时,B宽度同步增加同时监听A元素和B元素的变化,Container元素的宽度同样会增加。那么当A元素变化时监听B元素尺寸变化的回调会同步执行,并且A元素和Container元素变化的监听函数会推迟到下一帧执行并且控制台报错,因为有未执行的回调。

怎么避免

  1. 避免循环执行:在回调中判断达到目标值之后就不修改元素尺寸,导致回调意外触发。

  2. 延迟尺寸修改到下一帧:将执行顺序改为,帧1,A元素尺寸变化 -> 帧2,执行A元素尺寸变化的回调 -> 帧3,元素尺寸变化 -> ... 这样一直下去,就不会触发控制台报错,因为监听和触发是分帧进行的。

javascript 复制代码
const resizeObserver = new ResizeObserver((entries) => {
  requestAnimationFrame(() => {
    for (const entry of entries) {
      entry.target.style.width = `${entry.contentBoxSize[0].inlineSize + 10}px`;
    }
  });
});

参考

ResizeObserver

相关推荐
鱼樱前端1 小时前
今天介绍下最新更新的Vite7
前端·vue.js
coder_pig2 小时前
跟🤡杰哥一起学Flutter (三十四、玩转Flutter手势✋)
前端·flutter·harmonyos
万少2 小时前
01-自然壁纸实战教程-免费开放啦
前端
独立开阀者_FwtCoder2 小时前
【Augment】 Augment技巧之 Rewrite Prompt(重写提示) 有神奇的魔法
前端·javascript·github
yuki_uix2 小时前
AI辅助网页设计:从图片到代码的实践探索
前端
我想说一句2 小时前
事件机制与委托:从冒泡捕获到高效编程的奇妙之旅
前端·javascript
陈随易2 小时前
MoonBit助力前端开发,加密&性能两不误,斐波那契测试提高3-4倍
前端·后端·程序员
汤姆Tom2 小时前
JavaScript reduce()函数详解
javascript
小飞悟2 小时前
你以为 React 的事件很简单?错了,它暗藏玄机!
前端·javascript·面试
中微子2 小时前
JavaScript 事件机制:捕获、冒泡与事件委托详解
前端·javascript