前言

阅读本文你可以获取到以下3个知识点
通过原生javascript的API

  • 监听DOM元素的改变(文字、大小、背景等等)
  • 监听DOM元素之间是否相交等信息
  • 监听DOM元素大小改变,基本可以放弃全局监听window.rize

动动小手,先点赞再观看😂🤣🤣

MutationObserver

MutationObserver 创建一个观察器,提供了对监视DOM树更改的能力,是DOM3 Events规范的一部分

通过这个接口,我们可以轻松的实现对DOM 树变化的监听了😍

先来看下MutationObserver 都有哪些方法吧

方法 参数 描述
observe(targetNode, config) targetNode:DOM节点
config:监控配置(object)
开启监听DOM节点
disconnect() 取消监听,直到重新调用其observe()方法
takeRecords() 阻止MutationObserver监听并返回一个MutationRecord数组

这里config的可选参数有这些(至少写一项)

{
    childList: true,  // 观察目标子节点的变化,是否有添加或者删除
    attributes: true, // 观察属性变动
    subtree: true     // 观察后代节点,默认为 false
}

看完基本的属性后,下面来实际操作一下吧👌

<!--html-->
<div id="main">
    <h2>MutationObserver</h2>
    <div id="main2"></div>
</div>
<button id="btn-change">改变文字</button>
<button id="btn-cancel">取消监听</button>
// javascript
let mainEl = document.querySelector('#main')
let h2El = document.querySelector('#main>h2')
let btnChangeEl = document.querySelector('#btn-change')
let btnCancelEl = document.querySelector('#btn-cancel')

// 实例化MutationObserver,并传入监听回调
let observer = new MutationObserver((mutationsList) => {
    console.log('mutationsList:', mutationsList)
    //这里打印的Dom改变的信息
    // mutationsList:[{type: "attributes", target: h2, addedNodes: NodeList(0), removedNodes: NodeList(0), previousSibling: null, …}]
})

// 设置监听Dom并配置需要监听的选项
observer.observe(mainEl, {
    // 需要测试的话,自行配置
    attributes: true,
    childList: true,
    subtree: true
})

btnChangeEl.onclick = () => {
    h2El.style.height = '50px'
    h2El.innerText = '前端Jsoning'

    // const list = observer.takeRecords()
    // console.log('takeRecords:',list) 
    // 需要测试takeRecords方法的小伙伴,打开上面注释即可。
    // 这里打印的Dom改变的信息,并切不会进入实例中的回调
    // mutationsList:[{type: "attributes", target: h2, addedNodes: NodeList(0), removedNodes: NodeList(0), previousSibling: null, …}]
}
btnCancelEl.onclick = () => {
    // 取消监听
    observer.disconnect()
}

以上注释已经很详细了,需要测试的小伙伴,自行更改部分设置即可,这里就不在赘述了🤞

最后,再来看一下 MutationObserver兼容性(反正有polyfill,担心个🔨)

IntersectionObserver

IntersectionObserver 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法

这个接口可以监听到目标元素和祖先元素之间是否相交,通过IntersectionObserver 我们可以实现很多功能,例如懒加载、游戏里面的物体碰撞等等🎉

先来看下MutationObserver 都有哪些属性和方法吧

属性 参数 描述
IntersectionObserver.root 只读 所监听对象的祖先元素,默认为窗口
IntersectionObserver.rootMargin 只读 盒子交叉的偏移量,默认值为'0px 0px 0px 0px'
IntersectionObserver.thresholds 只读 阀值,0-1之间,监听目标与边界盒交叉区域的比例值
方法 参数 描述
observe(clallback, config) clallback: 元素相交超过阀值之后的回调
config: 配置生成MutationObserver实例的参数
监听目标元素
unobserve(targetNode) targetNode: 取消监听的元素节点(必传) 取消监听特定目标元素
takeRecords() 返回观察目标的对象数组
disconnect() 停止所有元素的监听

这里config的可选参数有这些:

{
    root: '', // 监听元素的祖先元素
    rootMargin: '', //元素之间交叉的偏移量,默认值为'0px 0px 0px 0px',
    threshold: '', //阀值,0-1之间,监听目标与边界盒交叉区域的比例值,这里配置会优先满足阀值后再去验证rootMargin
    
}

看完基本的属性后,下面来实际操作一下吧👌

<!--html-->
<style>
#box {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 100px;
    height: 100px;
    background-color: cadetblue;
    animation: animate 5s;
}
#content {
    position: relative;
    width: 400px;
    height: 400px;
    border: 1px solid #f00;
}

@keyframes animate {
    from {
        left: 10px;
    }
    to {
        left: 500px;
    }
}
</style>

 <div id="content">
    <div id="box"></div>
</div>
// javascript

let boxEl = document.querySelector('#box')
let contentEl = document.querySelector('#content')

const options = {
    root: contentEl,
    rootMargin: "10px 10px 10px 10px",
    threshold: 1.0
}
const intersectionObserver = new IntersectionObserver((entries) => {
    console.log(entries)
}, options)

// 开始监听
intersectionObserver.observe(boxEl);

// 停止监听一个元素
// intersectionObserver.unobserve(boxEl)

// 停止监听全部元素
// intersectionObserver.disconnect()

以上注释已经很详细了,需要测试的小伙伴,自行更改部分设置即可,这里就不在赘述了😜

最后,再来看一下 IntersectionObserver 的兼容性(反正有polyfill,担心个🔨)

ResizeObserver

ResizeObserver 创建一个新的ResizeObserver对象监听元素大小变化

这个接口可以监听到元素的变化,以前我们只能通过window.resize来监听页面变化,现在有了这个API任何元素都可以监听,赶脚很强大啊(该API目前还处于实验性,不过谷歌浏览器上目前已经有这个API了)🤳

先来看下ResizeObserver 都有方法吧

方法 参数 描述
observe(clallback, config) clallback: 元素变化之后的回调
config: 配置生成ResizeObserver实例的参数
监听目标元素
unobserve(targetNode) targetNode: 取消监听的元素节点(必传) 取消监听特定目标元素
disconnect() 停止所有元素的监听

由于这个API还处于实验性,config这个参数这里就不罗列了

看完基本的属性后,下面来实际操作一下吧👌

<!--html-->
<textarea id="main"></textarea>
// javascript

let mainEl = document.querySelector('#main')
const resizeObserver = new ResizeObserver(entries => {
    console.log(entries)
})

//拉动textarea的大小,即可看到输出
// 监听元素大小改变
resizeObserver.observe(mainEl) //ResizeObserverEntry [{target: textarea#main, contentRect:  {x: 2, y: 2, width: 143, height: 43, top: 2, …}}]

// 取消某个元素监听
//resizeObserver.unobserve(mainEl)

// 取消全部元素监听
//resizeObserver.disconnect()

最后,再来看一下 ResizeObserver 的兼容性(虽然还处于实验性有polyfill,担心个🔨)

总结

可以看到上面3个API,用法基本类似。对于这些较新的API我们可以尝试在项目中使用,可以极大的提升了工作效率和用户体验。码字不易,如果文章对你有帮助,不要吝啬你的赞哦👍👍👍,也可以关注我的公众号一起学习!!!

如果文章让你有收获,欢迎关注公众号,每日推送优质文章!!!


前端Jsoning
21 声望2 粉丝