IntersectionObserver实现图片懒加载(滚动动画)
先简单过下IntersectionObserver的属性跟、方法
var io = new IntersectionObserver(callback, option);
IntersectionObserver是浏览器原生提供的构造函数,这里的callback是回调函数,option是配置对象
属性
- root所监听对象的具体祖先元素。如果未传入值或值为null,则默认使用顶级文档的视窗。
- rootMarginrootMargin设置root区域的扩展部分,比如我们做懒加载的时候一般都会有一个预先加载的距离,这个可以通过设置rootMargin:'0px 0px 200px 0px',方向遵从上右下左。这样设置相当于如果一个元素距离底部还有200px就会被检测到。
- thresholdthreshold这个参数默认是0,表示当刚发生相交的时候会触发这个方法,但是触发后直到离开都不会再次触发了,所以这个参数的作用就是设置一些特定的相交比例,当到了就会自动触发。
方法
- observe(element):监听某个元素,传入要监听的元素作为参数
- unobserve(element):停止监听某个元素,传入停止监听的元素作为参数
- disconnect():使监听器停止工作
- takeRecords():返回所有正在监听的元素的IntersectionObserverEntry对象数组
实现懒加载
效果

直接上代码
//html
<div class="imgWarp">
<img alt="加载"
class="lazyload"
src=""
data-origin="https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1567391611&di=25036e46ab595855036662439ff9aeff&src=http://b-ssl.duitang.com/uploads/blog/201312/14/20131214145220_QQANN.jpeg">
<img alt="加载"
class="lazyload"
src=""
data-origin="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3617103641,169754897&fm=26&gp=0.jpg">
<img alt="加载"
class="lazyload"
src=""
data-origin="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2942419345,2278127334&fm=26&gp=0.jpg">
</div>
//js
function Observer () {
let images = document.querySelectorAll(".lazyload");
let observer = new IntersectionObserver(entries => {
entries.forEach(item => {
if (item.isIntersecting) {
item.target.src = item.target.dataset.origin; // 开始加载图片,把data-origin的值放到src
observer.unobserve(item.target); // 停止监听已开始加载的图片
}
});
},
{
rootMargin: "0px 0px -100px 0px" // 交叉过视图的100,才开始派发事件
}
);
images.forEach(item => observer.observe(item));
}
//scss也放上来把
.imgWarp {
display: flex;
flex-direction: column;
margin-top: 1000px;
.lazyload {
margin-top: 30px;
display: inline-block;
width: 120px;
height: 120px;
position: relative;
}
.lazyload:after {
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
background-color: #ccc;
}
}
复制代码
- 该方法还有一个好处,那就是当页面上某个节点存在横向滚动条的时候,一样应对自如:代码就不上了,可以自己试下

需要改动的只有三四行css代码。
实现动画

// html
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
//js
function onLoad () {
let list = document.querySelectorAll('ul li');
let observer = new IntersectionObserver(entries => {
entries.forEach(element => {
if (element.isIntersecting) {
element.target.classList.add("show"); // 增加show类名
observer.unobserve(element.target); // 移除监听
}
});
})
list.forEach(item => observer.observe(item));
}
//scss
ul {
margin-top: 500px;
display: flex;
width: 90%;
justify-content: center;
align-items: center;
flex-wrap: wrap;
text-align: center;
li {
width: 40%;
background-color: aqua;
width: 150px;
margin-bottom: 20px;
height: 150px;
&:nth-child(2n) {
margin-left: 20px;
}
&.show {
// 默认从左边进来
animation: left 1.4s ease;
// 偶数从右边进来
&:nth-child(2n) {
animation: right 1.4s ease;
}
}
}
}
@keyframes left {
from {
opacity: 0;
transform: translate(-40px, 20px) rotate(80deg); // right动画改成20px, 20px即可
}
to {
opacity: 1;
}
}
@keyframes right {
from {
opacity: 0;
transform: translate(40px, 20px) rotate(-80deg); // right动画改成20px, 20px即可
}
to {
opacity: 1;
}
}
复制代码
总结一波,大概就是这样bye!
作者:whoopshzh
链接:https://juejin.im/post/5d6cb1e5e51d4561a705bb5e
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
THE END