MutationObserver监听容器高度变化

1,909 阅读3分钟

前言

目前有新需求是指定路由前缀的所有路由都要添加背景颜色的图片,但是高度是根据具体页面内容决定的,因为数据驱动导致页面高度并不是进去就固定死,而且有按钮可以增加高度,所以必须去想办法监听高度变化,最后就采取了MutationObserver去监听页面高度,首先来介绍一个MutationObserver 官方介绍:MutationObserver官方地址

MutationObserver

Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知,Mutation Observer API 已经有很不错的浏览器兼容性,如果对IE10及以下没有要求的话,所以推荐使用

MutationObserver 特点

DOM 发生变动都会触发 Mutation Observer 事件。事件是同步触发,DOM 变化立即触发相应事件;Mutation Observer 是异步触发,DOM 变化不会马上触发,而是等当前所有 DOM 操作都结束后才触发,具体特点如下: 它等待所有脚本任务完成后,才会运行(即异步触发方式)。 它把 DOM 变动记录封装成一个数组进行处理,而不是一条条个别处理 DOM 变动。 它既可以观察 DOM 的所有类型变动,也可以指定只观察某一类变动。

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中一种或多种,否则会报错。其中各个属性意思如下:

childList 布尔值,表示是否应用到子节点的变动(新增、删除或者更改);
attributes 布尔值,表示是否应用到属性的变动;
characterData 布尔值,表示是否应用到节点内容或节点文本的变动;
subtree 布尔值,表示是否应用到是否将观察器应用于该节点的所有后代节点;
attributeFilter 数组,表示观察特定属性;
attributeOldValue 布尔值,表示观察 attributes 变动时,是否需要记录变动前的属性值;
characterDataOldValue 布尔值,表示观察 characterData 变动,是否需要记录变动前的值;

接下来上业务中的代码,是在vue3+js中进行开发

// HTML
<div class="patient-model-bg" :style="{ height: bgHeight }"></div>

// JS
// debounce是手动封装的防抖函数,因为MutationObserver监听变化次数频繁,通过防抖优化性能,300为时间,false为第一次是否触发
const debounceHeight = debounce(300, false)
// 通过mutationObserver来监听高度变化
const initMutationObserver = () => {
	// 通过nextTick在mounted中获取dom节点,rightRef就是我想要监听的DOM元素,通过绑定ref获取
    nextTick(() => {
    	// 获取不同环境下的MutationObserver 
        const MutationObserver = window.MutationObserver || window.webkitMutationObserver || window.MozMutationObserver
        const mutationObserver = new MutationObserver(() => {
        	// 通过debounceHeight确保300ms内没触发事件则获取到height高度给到bgHeight
            debounceHeight(() => {
                const height = window.getComputedStyle(rightRef.value)['height']
                bgHeight.value = height
            })
        })
        mutationObserver.observe(rightRef.value, {
            childList: true, // 子节点的变动(新增、删除或者更改)
            attributes: true, // 属性的变动
            attributeFilter: ['style'],
            characterData: true, // 节点内容或节点文本的变动
            subtree: true, // 是否将观察器应用于该节点的所有后代节点
        })
    })
}

onMounted(() => {
    initMutationObserver()
})

// CSS, 背景图片的样式代码,并无太大参考意义
.patient-model-bg {
    width: calc(100% - 70px);
    top: 0;
    left: 70px;
    z-index: 0;
    position: absolute;
    background: url('/src/assets/img/model-bg.png');
}

最后通过MutationObserver完成容器高度变化后自动增加bg背景图片高度,目前项目中已经使用 欢迎点赞收藏哦,各位大佬们!!!!!!!