我们在列表底部放一个参照元素,然后让交叉观察者去监听;
假设html结构如下:
<!-- 数据列表 -->
<ul>
<li>index</li> // 多个li
</ul>
<!-- 参照元素 -->
<div class="reference"></div>
然后监听参照元素:
new IntersectionObserver(entries => {
let item = entries[0]; // 拿第一个就行,反正只有一个
if (item.isIntersecting) console.log("滚动到了底部,开始请求数据");
}).observe(document.querySelector(".reference")); // 监听参照元素
实现元素吸顶的方式有很多种,如css的position: sticky,兼容性较差;如果用交叉观察者实现也很方便,同样也要放一个参照元素;
假设html结构如下:
<!-- 参照元素 -->
<div class="reference"></div>
<nav>我可以吸顶</nav>
假设scss代码如下:
nav {
&.fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
}
开始监听:
let nav = document.querySelector("nav");
let reference = document.querySelector(".reference");
new IntersectionObserver(entries => {
let item = entries[0];
let top = item.boundingClientRect.top;
// 当参照元素的的top值小于0,也就是在视窗的顶部的时候,开始吸顶,否则移除吸顶
if (top < 0) nav.classList.add("fixed");
else nav.classList.remove("fixed");
}).observe(reference);
但是有个问题,当你滚动的慢的时候,会掉进一个死循环: 当给nav增加fixed定位时,nav脱离了文档流,自然参考元素会往下掉,然后往下掉又发生了交叉,从而去除fixed定位,陷入一个死循环;
思考了一会,解决办法是,让参考元素绝对定位至nav的上方:
let nav = document.querySelector("nav");
let reference = document.querySelector(".reference");
reference.style.top = nav.offsetTop + "px";
// 以下代码不变 ... 这样,即使nav脱离的文档流,也不会影响参考元素的位置
假设html结构如下:
<ul>
<li></li> // 多个li
</ul>
假设scss代码如下:
ul {
li {
&.show {
// 默认从左边进来
animation: left 1s ease;
// 偶数从右边进来
&:nth-child(2n) {
animation: right 1s ease;
}
}
}
}
@keyframes left {
from {
opacity: 0;
transform: translate(-20px, 20px); // right动画改成20px, 20px即可
}
to {
opacity: 1;
}
}
然后开始监听:
let list = document.querySelectorAll("ul li");
let observer = new IntersectionObserver(entries => {
entries.forEach(item => {
if (item.isIntersecting) {
item.target.classList.add("show"); // 增加show类名
observer.unobserve(item.target); // 移除监听
}
});
});
list.forEach(item => observer.observe(item));