vue 监听元素高度的变化_如何优雅监听容器高度变化

本文介绍了如何使用MutationObserver监听DOM元素高度变化,特别是在使用iscroll或better-scroll等滚动插件时确保容器更新的方法。MutationObserver API可以异步捕获DOM变化,通过设置不同选项来关注所需类型的变动。文章还探讨了ResizeObserver作为另一种监听元素尺寸变化的实验性接口,以及在ResizeObserver不兼容时的备用方案,如iframe模拟窗口resize事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

老鸟:怎样去监听 DOM 元素的高度变化呢?

菜鸟:哈哈哈哈哈,这都不知道哦,用 onresize 事件鸭!

老鸟扶了扶眼睛,空气安静几秒钟,菜鸟才晃过神来。对鸭,普通 DOM 元素没有 onresize 事件,只有在 window 对象下有此事件,该死,又双叒叕糗大了。

哈哈哈哈,以上纯属虚构,不过在最近项目中还真遇到过对容器监听高(宽)变化:在使用 iscroll 或 better-scroll 滚动插件,如果容器内部元素有高度变化要去及时更新外部包裹容器,即调用 refresh() 方法。不然就会造成滚动误差(滚动不到底部或滚动脱离底部)。

可能我们一般处理思路:在每次 DOM 节点有更新(删除或插入)后就去调用 refresh(),更新外部容器。

对异步资源(如图片)加载,使用onload 监听每次加载完成,再去调用 refresh(),更新外部容器。

这样我们会发现,如果容器内部元素比较复杂,调用会越来越繁琐,甚至还要考虑到用户使用的每一个操作都可能导致内部元素宽高变化,进而要去调整外部容器,调用 refresh()。

实际上,不管是对元素的哪种操作,都会造成它的属性、子孙节点、文本节点发生了变化,如果能能监听得到这种变化,这时只需比较容器宽高变化,即可实现对容器宽高的监听,而无需关系它外部行为。DOM3 Events 规范为我们提供了 MutationObserver 接口监视对 DOM 树所做更改的能力。

MutationObserver

Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。

PS Mutation Observer API 已经有很不错的浏览器兼容性,如果对IE10及以下没有要求的话。

MutationObserver 特点

DOM 发生变动都会触发 Mutation Observer 事件。但是,它跟事件还是有不用点:事件是同步触发,DOM 变化立即触发相应事件;Mutation Observer 是异步触发,DOM 变化不会马上触发,而是等当前所有 DOM 操作都结束后才触发。总的来说,特点如下:它等待所有脚本任务完成后,才会运行(即异步触发方式)。

它把 DOM 变动记录封装成一个数组进行处理,而不是一条条个别处理 DOM 变动。

它既可以观察 DOM 的所有类型变动,也可以指定只观察某一类变动。

MutationObserver 构造函数

MutationObserver 构造函数的实例传的是一个回调函数,该函数接受两个参数,第一个是变动的数组,第二个是观察器的实例。var observer = new MutationObserver(function (mutations, observer){

mutations.forEach(function (mutaion) {

console.log(mutation);

})

})

MutationObserver 实例的 observe() 方法

observe 方法用来执行监听,接受两个参数:第一个参数,被观察的 DOM 节点;

第二个参数,一个配置对象,指定所要观察特征。var $tar = document.getElementById('tar');

var option = {

childList: true, // 子节点的变动(新增、删除或者更改)

attributes: true, // 属性的变动

characterData: true, // 节点内容或节点文本的变动

subtree: true, // 是否将观察器应用于该节点的所有后代节点

attributeFilter: ['class', 'style'], // 观察特定属性

attributeOldValue: true, // 观察 attributes 变动时,是否需要记录变动前的属性值

characterDataOldValue: true // 观察 characterData 变动,是否需要记录变动前的值

}

mutationObserver.observe($tar, option);

option 中,必须有 childList、attributes和characterData中一种或多种,否则会报错。其中各个属性意思如下:childLi

要在 Vue监听 DOM 元素高度变化,您可以使用 Vue 的 `$nextTick` 方法和 `Intersection Observer API`。 首先,在模板中,您需要使用一个具有固定高度的外层元素包裹您要监听高度变化元素,例如: ```html <template> <div class="container"> <div class="content" ref="myContent"></div> </div> </template> <style> .container { height: 200px; overflow: auto; } .content { height: 400px; } </style> ``` 上面的代码中,我们在外层使用了一个具有固定高度和滚动条的容器,并在内部添加了一个高度为 400px 的 `<div>` 元素。 接下来,在 Vue 实例中,您需要通过 `$refs` 来获取要监听高度变化元素,并使用 `Intersection Observer API` 来监听元素变化,例如: ```js export default { mounted() { const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { this.$nextTick(() => { console.log(this.$refs.myContent.clientHeight) }); } }); }); observer.observe(this.$refs.myContent); } } ``` 上面的代码中,我们在 Vue 实例的 `mounted` 生命周期钩子中创建了一个 `IntersectionObserver`,并通过 `$refs` 获取了要监听高度变化元素。然后,我们使用 `IntersectionObserver` 监听元素变化,并在元素进入视口时,使用 `$nextTick` 方法获取元素的新高度,并打印到控制台中。 需要注意的是,`$nextTick` 方法会在 DOM 更新后执行回调函数,以确保获取到的元素高度是最新的。这是因为 Vue 的更新是异步的,在修改 DOM 后,您无法立即获取到最新的 DOM 元素高度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值