Uni-app H5 环境下 ResizeObserver 监听 mp-html 动态高度

在 Uni-app 混合开发中,处理 H5 WebView 环境下富文本内容的动态高度是一个常见难题。本文聚焦于 mp-html 组件的特定场景,分析 ResizeObserver 的应用价值与潜在风险。

1. 业务背景:mp-html 渲染的遮罩层动态适配

在结果报告业务中,我们需要根据 mp-html 渲染的 Markdown 内容高度,动态决定是否展示"解锁完整结果"的遮罩。核心挑战在于:

  • 富文本内容高度不固定:包含图片、表格、代码块等多种元素
  • 异步资源加载:远程图片加载导致高度"跳变"
  • 响应式布局:不同屏幕宽度下内容高度不同

2. 传统方案:uni.createSelectorQuery 的局限性

typescript 复制代码
// 常规做法:使用 nextTick + 选择器查询
this.$nextTick(() => {
  uni.createSelectorQuery()
    .select('#content')
    .boundingClientRect(rect => {
      this.contentHeight = rect.height;
    })
    .exec();
});

缺点分析

问题 具体表现 影响
单次快照 仅获取查询时刻的尺寸 图片加载后高度变化无法感知
时机难控 nextTick 时资源可能未加载完成 拿到的是占位符高度
频繁调用 为"实时"需定时轮询 性能开销大

核心痛点:高度跳变

富文本中的图片加载过程:

  1. DOM 解析 → 图片高度为 0 或占位符
  2. 网络请求 → 异步等待
  3. 图片渲染 → 页面重排,高度瞬间变化

createSelectorQuery 只能捕获第 1 步的高度,导致遮罩层定位错误。

3. ResizeObserver 方案

为什么 ResizeObserver 适合 mp-html 场景

ResizeObserver 是浏览器原生 API,专门用于监听元素尺寸变化。对于 mp-html 渲染的富文本场景,它能精准捕捉:

  • 图片加载完成后的高度撑开
  • 字体大小变化导致的行高调整
  • 屏幕旋转引起的宽度变化

代码实现

typescript 复制代码
// #ifdef H5
const observer = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const newHeight = entry.contentRect.height;
    if (newHeight > 0) {
      blocks.value[index].height = newHeight;
      emit("ready");
    }
  }
});

const el = document.getElementById("block-" + index);
if (el) observer.observe(el);
// #endif

4. 优缺点深度分析

✅ 优点

优点 说明
主动监听 无需手动触发,尺寸变化自动回调
异步友好 图片加载完成后的高度变化精准捕捉
高性能 浏览器原生实现,相比 MutationObserver + 轮询更高效
精准 提供 contentRect.height 精确像素值

⚠️ 缺点

缺点 说明 应对方案
H5 专属 仅支持浏览器环境,小程序/App 端不可用 需结合 #ifdef H5 条件编译
兼容性 IE 浏览器不支持 考虑 polyfill 或降级方案
内存泄漏风险 组件销毁时未断开观察 onUnmounted 中调用 observer.disconnect()
触发过于频繁 每次微小的尺寸变化都会触发 结合防抖/节流处理

注意事项

typescript 复制代码
// ❌ 错误:未清理观察者
onUnmounted(() => {
  // 忘记 disconnect 导致内存泄漏
});

// ✅ 正确:组件销毁时断开观察
onUnmounted(() => {
  observer?.disconnect();
});

5. 适用场景判断

场景 推荐方案
H5 环境 + mp-html 动态高度 ✅ ResizeObserver
需要兼容小程序端 ❌ 需降级为 createSelectorQuery + 定时器
静态内容(高度不变) ❌ 无需使用,单次查询即可
简单业务(低频变化) 可用 createSelectorQuery + 定时轮询

6. 总结

在 Uni-app H5 环境下处理 mp-html 富文本的动态高度时,ResizeObserver 是目前最优雅的解决方案。它能完美解决异步图片加载导致的"高度跳变"问题,但需要注意:

  1. 条件编译:仅在 H5 环境下使用
  2. 资源清理:组件销毁时断开观察
  3. 降级兼容:需要考虑不支持 ResizeObserver 的旧版浏览器

通过合理使用 ResizeObserver,可以实现丝滑的 WebView 体验,避免遮罩层错位等问题。

相关推荐
wenzhangli71 小时前
Ooder A2UI 核心架构深度解析:WEB 拦截层的设计与实现
前端·架构
前端百草阁2 小时前
【前端性能优化全链路指南】从开发编写到构建运行的多维度实践
前端·性能优化
女生也可以敲代码2 小时前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
ZhengEnCi2 小时前
M5-markconv自定义CSS样式指南 📝
前端·css·python
IT_陈寒2 小时前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
xingpanvip2 小时前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua
@PHARAOH3 小时前
WHAT - GitLens supercharged 插件
前端
TT模板3 小时前
苹果cms整合西瓜播放器XGplayer插件支持跳过片头尾
前端·html5
Wect4 小时前
React 性能优化精讲
前端·react.js·性能优化
追风筝的人er4 小时前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
前端·vue.js·后端