52、window.resize、ResizeObserver、MutationObserver的区别以及 各自适用场景
2026/4/14 19:37:48 网站建设 项目流程

目录

一、先给一个面试里的标准回答

二、先看三者的核心区别

三、分别说清楚

1. window.resize

监听的是什么?

示例

特点

局限

2. ResizeObserver

监听的是什么?

示例

特点

最适合

3. MutationObserver

监听的是什么?

示例

特点

注意

四、三者最本质的差别

五、各自适用场景

1. window.resize 适用场景

典型场景

示例

不适合

2. ResizeObserver 适用场景

典型场景

示例

不适合

3. MutationObserver 适用场景

典型场景

示例

不适合

六、一个容易混淆的问题:为什么监听元素尺寸不能只用 MutationObserver?

七、一个容易混淆的问题:为什么监听元素变化不能只用 window.resize?

八、在 Vue 项目里怎么选?

在 Vue 中:

用 window.resize

用 ResizeObserver

用 MutationObserver

九、Vue 面试里推荐的回答方式

高分回答模板

十、代码对比示例

1. 监听窗口变化

2. 监听元素尺寸变化

3. 监听 DOM 结构变化

十一、面试官可能继续追问什么?

追问1:ResizeObserver 和 MutationObserver 能互相替代吗?

追问2:如果元素尺寸变化是因为 class 改变导致的呢?

追问3:这几个 API 都要注意什么?

window.resize

ResizeObserver

MutationObserver

十二、简洁背诵版

十三、一句话总结


这是一个很典型的面试题。
如果只背概念,面试官会继续追问:

  • 它们分别监听什么
  • 有什么本质区别
  • 谁更适合监听元素尺寸变化
  • 谁更适合监听 DOM 结构变化
  • 实际项目中怎么选

所以回答时最好按这几个维度展开。


一、先给一个面试里的标准回答

window.resizeResizeObserverMutationObserver都和页面变化监听有关,但监听的对象完全不同。

  • window.resize监听的是浏览器窗口尺寸变化
  • ResizeObserver监听的是某个 DOM 元素尺寸变化
  • MutationObserver监听的是DOM 结构、属性、文本内容变化

如果我要监听页面整体响应式变化,可以用window.resize
如果我要监听某个容器宽高变化,比如图表、自适应布局,优先用ResizeObserver
如果我要监听节点增删、属性变更、文本变化,比如富文本、第三方组件 DOM 变化,就用MutationObserver

三者不是替代关系,而是解决不同类型的问题。

这段已经可以作为一个不错的面试开场。


二、先看三者的核心区别

API监听对象监听内容常见用途
window.resize浏览器窗口视口宽高变化响应式布局、全局重排
ResizeObserverDOM 元素元素宽高变化图表自适应、容器尺寸监听
MutationObserverDOM 节点节点增删、属性、文本变化监听 DOM 结构变化、第三方库内容变化

三、分别说清楚


1.window.resize

监听的是什么?

监听的是:

浏览器窗口大小变化

比如你拖动浏览器窗口、切换屏幕方向,都会触发。

示例

window.addEventListener('resize', () => { console.log(window.innerWidth, window.innerHeight) })

特点

  • 监听范围是整个窗口
  • 无法直接知道某个具体元素尺寸是否变化
  • 元素变大变小不一定会触发它

局限

假设有这样一个场景:

  • 侧边栏展开
  • 主内容区域变窄
  • 浏览器窗口根本没变

这时某个元素宽度变化了,但window.resize不会触发


2.ResizeObserver

监听的是什么?

监听的是:

某个元素盒子尺寸变化

比如:

  • 容器宽度变化
  • 内容撑开高度
  • flex / grid 重排导致元素尺寸变化

示例

const observer = new ResizeObserver((entries) => { entries.forEach(entry => { console.log(entry.contentRect.width, entry.contentRect.height) }) }) observer.observe(document.querySelector('.box'))

特点

  • 精准监听元素本身尺寸
  • 不依赖窗口变化
  • window.resize更适合组件级监听

最适合

  • 图表容器自适应
  • 卡片布局重算
  • 弹窗内容高度变化
  • 表格容器变化
  • 自适应组件

3.MutationObserver

监听的是什么?

监听的是:

DOM 的变更

包括:

  • 子节点新增 / 删除
  • 属性变化
  • 文本内容变化

示例

const target = document.querySelector('.box') const observer = new MutationObserver((mutationsList) => { mutationsList.forEach(mutation => { console.log(mutation.type) }) }) observer.observe(target, { childList: true, attributes: true, characterData: true, subtree: true })

特点

它关注的是:

  • DOM 结构有没有变
  • 属性有没有改
  • 文本有没有更新

不是专门监听尺寸的。

注意

DOM 变化不一定导致尺寸变化,尺寸变化也不一定来自 DOM 变更。

例如:

  • 给元素加个 class,可能尺寸变
  • 字体加载后元素尺寸变,但 DOM 结构可能没变
  • 父容器布局变化导致子元素宽度变化,DOM 也可能没变

所以MutationObserver不能完全替代ResizeObserver


四、三者最本质的差别

可以用一句话记:

  • window.resize:看窗口
  • ResizeObserver:看尺寸
  • MutationObserver:看DOM 变更

五、各自适用场景


1.window.resize适用场景

适合监听全局视口变化。

典型场景

  • 响应式布局切换
  • 重新计算 rem / vw
  • 浏览器缩放、横竖屏切换处理
  • 页面级图表整体重排
  • 监听断点变化

示例

window.addEventListener('resize', () => { if (window.innerWidth < 768) { console.log('移动端布局') } else { console.log('桌面端布局') } })

不适合

  • 精准监听某个 DOM 元素宽高变化

2.ResizeObserver适用场景

适合监听元素级别尺寸变化。

典型场景

  • ECharts 容器变化后chart.resize()
  • 表格容器变化后重算列宽
  • 抽屉、弹窗、卡片内容区变化
  • 监听列表项高度变化
  • 组件自适应布局

示例

const ro = new ResizeObserver(([entry]) => { console.log('容器尺寸变化:', entry.contentRect.width) }) ro.observe(container)

不适合

  • 监听 DOM 增删、属性变化细节

3.MutationObserver适用场景

适合监听 DOM 结构和属性层面的变化。

典型场景

  • 监听某个容器下节点被动态插入
  • 监听富文本编辑器内容变更
  • 监听第三方库生成的 DOM
  • 监听属性 class/style/data-* 变化
  • 监听异步渲染节点出现

示例

const mo = new MutationObserver((list) => { list.forEach(item => { if (item.type === 'childList') { console.log('子节点变化') } }) }) mo.observe(target, { childList: true, subtree: true })

不适合

  • 单纯做尺寸监听

六、一个容易混淆的问题:为什么监听元素尺寸不能只用MutationObserver

这是高频追问。

你可以这样答:

因为MutationObserver监听的是 DOM 变更,不是最终布局结果。
元素尺寸变化不一定来自 DOM 结构变化,也可能是 CSS、字体加载、父容器变化、flex 布局计算导致的。
所以如果目标是监听尺寸变化,应该优先用ResizeObserver,而不是用MutationObserver间接推测。

这个回答会很加分。


七、一个容易混淆的问题:为什么监听元素变化不能只用window.resize

你可以这样答:

因为window.resize只能感知浏览器视口变化,而元素尺寸变化很多时候跟窗口没关系。
比如侧边栏展开、内容增多、父容器布局变化,都可能让元素尺寸变化,但不会触发window.resize
所以它更适合页面级监听,而不是元素级监听。


八、在 Vue 项目里怎么选?

这个问题如果你答上,会更像有实战经验。


在 Vue 中:

window.resize

当你关注的是:

  • 整个页面断点变化
  • 屏幕宽度变化
  • rem、响应式布局切换

ResizeObserver

当你关注的是:

  • 某个组件根节点尺寸变化
  • 图表容器变化
  • 弹窗/表格/列表布局变化

MutationObserver

当你关注的是:

  • 某个区域 DOM 被第三方库改写
  • 节点异步插入
  • class/style/属性变化
  • 富文本编辑器内容结构变化

九、Vue 面试里推荐的回答方式

可以按照“定义 + 区别 + 场景 + 选型”来答。


高分回答模板

这三个 API 都和页面变化监听有关,但关注点不同。

window.resize监听的是浏览器窗口大小变化,适合做全局响应式布局、断点切换这类页面级逻辑;
ResizeObserver监听的是具体 DOM 元素的尺寸变化,适合图表自适应、容器宽高监听、组件自适应;
MutationObserver监听的是 DOM 结构和属性变化,比如节点新增删除、属性变更、文本变化,适合监听第三方组件插入节点、富文本内容变化等。

如果我要监听“元素宽高变化”,我会优先选ResizeObserver
如果我要监听“DOM 结构是否变化”,我会选MutationObserver
如果我要监听“窗口变化导致的整体布局变化”,我会用window.resize

所以三者不是谁替代谁,而是作用层级不同:window.resize关注窗口,ResizeObserver关注尺寸,MutationObserver关注 DOM 变更。


十、代码对比示例


1. 监听窗口变化

window.addEventListener('resize', () => { console.log('窗口变化', window.innerWidth, window.innerHeight) })

2. 监听元素尺寸变化

const box = document.querySelector('.box') const resizeObserver = new ResizeObserver(([entry]) => { console.log('元素尺寸变化', entry.contentRect.width, entry.contentRect.height) }) resizeObserver.observe(box)

3. 监听 DOM 结构变化

const box = document.querySelector('.box') const mutationObserver = new MutationObserver((mutations) => { mutations.forEach(mutation => { console.log('变化类型:', mutation.type) }) }) mutationObserver.observe(box, { childList: true, attributes: true, subtree: true })

十一、面试官可能继续追问什么?


追问1:ResizeObserverMutationObserver能互相替代吗?

不能完全替代。
ResizeObserver关注的是布局结果,也就是尺寸;
MutationObserver关注的是 DOM 层面的变更。
二者关注点不同。


追问2:如果元素尺寸变化是因为 class 改变导致的呢?

MutationObserver可以监听到 class 属性变化,
但它只能告诉你“属性变了”,不能直接告诉你最终尺寸是多少。
如果业务目标是获取最终宽高,还是应该用ResizeObserver


追问3:这几个 API 都要注意什么?

window.resize

  • 高频触发,注意节流/防抖
  • 组件销毁时移除监听

ResizeObserver

  • 注意disconnect()
  • 避免在回调中直接引发无限尺寸变更

MutationObserver

  • 配置项别开太大,否则成本高
  • 注意disconnect()
  • subtree: true时可能监听范围很大

十二、简洁背诵版

window.resize监听浏览器窗口大小变化,适合页面级响应式逻辑;
ResizeObserver监听 DOM 元素尺寸变化,适合图表、自适应容器;
MutationObserver监听 DOM 结构、属性和文本变化,适合监听节点增删或第三方 DOM 变更。

如果关注的是窗口,用window.resize
如果关注的是元素宽高,用ResizeObserver
如果关注的是 DOM 变化,用MutationObserver


十三、一句话总结

window.resize看窗口,ResizeObserver看尺寸,MutationObserver看 DOM 变更。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询