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

相关推荐
患得患失94915 分钟前
【前端】【vscode】【.vscode/settings.json】为单个项目配置自动格式化和开发环境
前端·vscode·json
飛_17 分钟前
解决VSCode无法加载Json架构问题
java·服务器·前端
YGY Webgis糕手之路3 小时前
OpenLayers 综合案例-轨迹回放
前端·经验分享·笔记·vue·web
90后的晨仔3 小时前
🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?
前端·vue.js
Ares-Wang3 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
90后的晨仔3 小时前
Vue 模板语法完全指南:从插值表达式到动态指令,彻底搞懂 Vue 模板语言
前端·vue.js
德育处主任4 小时前
p5.js 正方形square的基础用法
前端·数据可视化·canvas
烛阴4 小时前
Mix - Bilinear Interpolation
前端·webgl
90后的晨仔4 小时前
Vue 3 应用实例详解:从 createApp 到 mount,你真正掌握了吗?
前端·vue.js
德育处主任4 小时前
p5.js 矩形rect绘制教程
前端·数据可视化·canvas