Introducción
IntersectionObserver proporciona una forma de observar de forma asincrónica los cambios en la intersección de un elemento de destino con un elemento antecesor o la ventana gráfica del documento de nivel superior.
IntersectionObserver recibe dos parámetros, devolución de llamada y opciones. Las opciones son opcionales y tienen valores predeterminados.
const observador = new IntersectionObserver(devolución de llamada[, opciones]);
uso básico
<div class="viewableArea">
指定的可视区域
<div class="target">被监听的目标元素</div>
内容很多,都多到出现滚动条了。内容很多,都多到出现滚动条了。内容很多,都多到......
</div>
const specifiedViewableArea = document.getElementsByClassName('viewableArea')[0];
const target = document.getElementsByClassName('target')[0];
const options = {
// 指定可视区域
root: specifiedViewableArea,
// 给可视区域添加”虚拟“外边距
rootMargin: '0px',
// 当目标元素与指定可视区发生交叉,且目标元素出现在可视区的部分占目标元素的比例是0.33时,触发callback的调用。
threshold: 0.33,
};
const callback = (entries: IntersectionObserverEntry[], observer?: IntersectionObserver) => {
entries.forEach((entry) => {
console.log('entry:', entry);
// todo 根据entry里的信息判断是否要你想做的事情
if (entry.isIntersecting) {
console.log('intersecting');
} else {
console.log('not intersecting');
}
});
};
// 创建并返回一个IntersectionObserver交叉观察者实例,并传入 callback回到函数 和 options配置项。
// callback 在什么时候调用? ----> 当目标元素与可视区域交叉的部分占目标元素的比例达到options设置的阈值threshold时调用。
// 两个时机:当目标元素进入可视区时、当目标元素离开可视区时。
const observer = new IntersectionObserver(callback, options);
// 开始观察目标元素
observer.observe(target);
ejemplo
Ejemplo 1
const options = {
root: specifiedViewableArea,
rootMargin: '0px',
// threshold可以是一个number,值在0~1之间。
// 这里,当目标元素的只有三分之一出现在可视区时,触发callback
threshold: 0.33,
};
Ejemplo 2
const options = {
root: specifiedViewableArea,
rootMargin: '0px',
// threshold 可以是一个升序的数组。
// 当目标元素在进入或离开可视区域时,交叉区域的阈值满足数组中任意一个值,都会触发callback。
threshold: [0.3, 0.7],
};
estado 1:
estado 2:
estado 3:
Ejemplo 3
const options = {
root: specifiedViewableArea,
// 添加虚拟边界作为可视区的一部分,这也作为可视区和目标元素交叉的一部分。
rootMargin: '50px',
threshold: 0.25,
};
Instrucciones de API relacionadas
IntersecciónObservador
interface IntersectionObserver {
// 要监听的可视区域,默认是顶级文档的视窗。
readonly root: Element | Document | null;
// 计算可视区交叉时添加到根(root)边界盒bounding box的矩形偏移量,默认值为"0px 0px 0px 0px"。
// 当计算交叉时,会把它看作是指定可视区的一部分。
readonly rootMargin: string;
// 一个按升序排列的阈值列表,当目标元素在进入或离开可视区域时,交叉区域的阈值满足数组中任意一个值,都会触发callback。默认值为0。
readonly thresholds: ReadonlyArray<number>;
// 停止所有监听。
disconnect(): void;
// 开始监听目标元素。
observe(target: Element): void;
// 返回所有被观察目标的记录。
takeRecords(): IntersectionObserverEntry[];
// 取消监听目标元素。
unobserve(target: Element): void;
}
IntersecciónObservadorEntrada
Esta interfaz registra la información cuando el elemento de destino se cruza con el área visible especificada en un momento de transición específico.
interface IntersectionObserverEntry {
// 返回目标元素的边界信息,包括left、right、top、buttom、width、height、x、y。
readonly boundingClientRect: DOMRectReadOnly;
// 返回目标元素出现在可视区的比例。
readonly intersectionRatio: number;
// 返回目标元素和可视区的相交区域的边界信息。
readonly intersectionRect: DOMRectReadOnly;
// 当目标元素出现在可视区时返回true。当目标元素从可视区消失时返回false。这两种情况均触发callback的调用。
readonly isIntersecting: boolean;
// 可视区的边界信息。
readonly rootBounds: DOMRectReadOnly | null;
// 目标元素。
readonly target: Element;
// 从开始监听到发生交叉的时间戳。
readonly time: DOMHighResTimeStamp;
}
solicitud
Cuando la página se desplaza, realiza efectos de animación.
const observer = new IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
if (entries[0].intersectionRatio <= 0.33) {
// 动画相关代码...
}
},
{
root: specifiedViewableArea,
threshold: 0.33
}
);
observer.observe(target);
Recursos de carga diferida
Por ejemplo, carga diferida de recursos de imagen.
const observer = new IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// 加载图片的相关代码... 给img的src属性赋值
// 取消对当前元素的监听
observer.unobserve(entry.target);
}
});
}
);
// 观察所有要加载图片的元素
const imgList = document.querySelectorAll('img');
imgList.forEach((img) => observer.observe(img));
exposición enterrada
Cuando el elemento de destino aparezca completamente en el área visible especificada, realice la exposición del punto enterrado.
const observer = new IntersectionObserver(
(entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
// 目标元素完全暴露在可视区域中
if (entry.intersectionRatio === 1) {
//埋点曝光相关代码...
// 取消对当前元素的监听
observer.unobserve(entry.target);
}
});
},
{
root: null,
threshold: 1,
}
);
// 观察要进行埋点曝光的元素
observer.observe(target)
estudio de referencia
Documento de MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
Artículo de Nugget: https://juejin.cn/post/6844903874302574599