【今日文章】:Web端常用的Observer监听器
MutationObserver
用于
监听Dom变化
<body>
<div id="elem"></div>
<div id="son"></div>
<script type="text/javascript">
const elem = document.querySelector("#elem");
const son = document.querySelector("#son");
// 参数
// 1. mutationsList是发生变化的数组
// 2. observer是当前MutationObserver的实例对象
const observer = new MutationObserver((mutationsList, observer) => {
// 【在这里进行业务操作】。
console.log(mutationsList);
});
// 这里填写的是,要监听的对象。
// 比如【标签变化】、【子节点变化】、【属性变化】等等。
observer.observe(elem, {
childList: true,
});
// elem变化的时候,MutationObserver会监听到。
elem.textContent = "小黑";
elem.appendChild(son);
elem.removeChild(son);
</script>
</body>
IntersectionObserver
异步观察
元素与浏览器视口的交集变化
。
就是Dom元素
与 浏览器窗口的交集。
// 1. 创建一个观察者实例
// 参数:entries是有交集的所有Dom元素。
// observer 是被观察的对象。
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
// entry.isIntersecting 判断目标元素是否在视口中。
if (entry.isIntersecting) {
console.log('目标元素在视口中!');
} else {
console.log('目标元素不在视口中.');
}
});
});
// 2.观察某个元素
const targetElement = document.querySelector('.some-class');
observer.observe(targetElement);
// 3.停止观察
// 如果你不再需要观察某个元素,你可以调用:
observer.unobserve(targetElement);
// 如果你想停止观察所有元素,你可以调用:
observer.disconnect();
// 4.配置选项
//当创建 IntersectionObserver 实例时,你可以提供一个配置对象,该对象有以下属性:
const options = {
root: document.querySelector('.scroll-container'), // 观察目标的父元素,如果不设置,默认为浏览器视口,一般用默认的
rootMargin: '10px', // 增加或减少观察目标的可见区域大小,一般用默认的
threshold: [0] //取值在0-1之间。 也就是目标元素与浏览器的交集的大小。当观察目标的可见比例达到这些阈值时会触发【回调函数】
};
const observer = new IntersectionObserver(callback, options);
这个Observer非常常用,常用于【图片懒加载】【下拉加载】【广告计费】等
// 图片懒加载
const observer = new IntersectionObserver((entries) => {
// entries是所有与浏览器窗口有交集的图片
entries.forEach(entry => {
// 如果有交集
if (entry.isIntersecting) {
//1. 给<image>赋值真正的图片
const img = entry.target;
img.src = img.dataset.trueImg;
//2. 对已经赋值上图片的元素,取消监听。
observer.unobserve(img);
}
});
});
// 获取所有的img,比如现在有100个<image>。图片的底图都是loading的图片。
document.querySelectorAll('img[data-lazy]').forEach(img => {
observer.observe(img);
});
// 首先我们要知道的是,如何加载更多?
// 当【loading出现的时候】,我们就需要加载更多。
const observer = new IntersectionObserver((entries) => {
const entry=entries[0]
// loading 与 窗口的交集
if (entry.isIntersecting) {
loadMoreContent(); // 你的加载更多内容的函数
}
},{
root: null,//使用默认的根元素(视窗)
threshold: 0.5,//元素可见度超过 50% 时触发回调
});
// 监听[.load-more-trigger]
const loadMoreTrigger = document.querySelector('.load-more-trigger');
observer.observe(loadMoreTrigger);
const observer = new IntersectionObserver((entries, self) => {
const entry=entries[0]
// 视频与窗口交集变了,也就是浏览器滚动了,不显示整个视频了
if (!entry.isIntersecting) {
video.pause()
}else{
video.paly()
}
});
// 监听[.video]
const video = document.querySelector('.video');
observer.observe(video);