文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、IntersectionObserver是什么?
IntersectionObserver接口,提供了一种异步观察目标元素与其祖先元素或顶级文档视窗交叉状态的方法。
二、使用方法
1.创建观察对象
var observer = new IntersectionObserver(callback, options)
2.观察指定DOM对象
observer.observe( DOM对象 )
observer观察者对象在观察元素是否进入视口、祖先元素的时候,不管元素是否进入,都会触发观察者对象的回调函数!
示例:
var box = document.querySelector('.box')
var observer = new IntersectionObserver(function(entries){
console.log(entries)
})
observer.observe(box)
大家可以发现,程序会默认执行一次输出,因为box盒子默认就在视口当中,所以会触发一次;
当你滚动页面,box离开视口以后,还会再执行一次;所以:元素在视口中也会触发观察者对象,不在视口中也会触发观察者对象。
3.参数详解
1. callback 配置参数:
var observer = new IntersectionObserver(function(entries,observer){
//回回调函数接受两个参数,第二个可以不写,因为用处不大
}, options)
回调函数接受两个参数,分别是:所有被监听的dom对象集合,一般用 entries
表示;
以及观察者对象,一般用 observer
表示,可写可不写。
在 entries
集合中的每一个元素都是被监听的对象,被监听的对象上有一些属性,其中比较常用的属性是:
isIntersecting
true当前元素进入视口 false当前元素离开视口
target
当前DOM对象
这里要特别注意,要操作entries
集合中的Dom对象,记得加索引!
示例:
var box = document.querySelector('.box');
var observer = new IntersectionObserver(function(entries){
console.log( entries[0].isIntersecting );
})
observer.observe(box)
2. options 配置参数:
options是一个对象,有三个参数:
第一个参数: root: 祖先级对象 | null
root属性的值可以是一个祖先级对象,这时,主要的是针对局部的滚动效果。
当root属性不写,或者值为null时,表示的是监听DOM元素与当前视口的交叉关系!
第二个参数: rootMargin: 视口的外延值
相当于扩大视口的范围
rootMargin 属性是规定视口的外延值,相当于扩大了视口的范围,用于提早触发观察者回调函数
这里直接上图解释:
第三个参数:threshold:0-1
就是当被观察者进入视口百分之多少时触发观察者
threshold默认值是0,表示:刚进入时就触发观察者的回调函数;完全离开时,在触发观察的回调
当threshold的值是1,表示:当被监听元素完全进入视图在触发观察者的回调函数; 当元素刚离
那如果过设置一个中间值呢?请看下图:
三、使用 IntersectionObserver 完成一些案例
Dom进入页面的加载动画效果(示例)
代码如下:
<style>
.show{
transform: translateY(0) scale(1);
opacity: 1;
}
.hide{
transform: translateY(100%) scale(0);
opacity: 0;
}
//css样式可自行决定,这里虽然没写,但别忘了添加transtion过渡属性,让动画更加平滑
<style>
<body>
<ul class="list">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</body>
<script>
var lis = document.querySelectorAll(".list li");
var observer = new IntersectionObserver(function(entries){
// 2 这里会接收到所有被观察的 dom 对象
for( var i = 0; i < entries.length; i++ ){
//遍历所以被观察对象,判断其是否出现在视口
if( entries[i].isIntersecting ){
//为true则表示出现在视口,然后为其添加出现样式
entries[i].target.classList.remove('hide');
entries[i].target.classList.add('show')
}
else{
//为flase则表示消失在视口,然后为其添加消失样式
if( entries[i].boundingClientRect.top > 0 ){
//这里是判断li是否是往下消失
entries[i].target.classList.remove('show');
entries[i].target.classList.add('hide')
}
}
}
});
for( var i = 0; i < lis.length; i++ ){
observer.observe(lis[i])
// 1 给所有li添加监听观察
}
</script>
给dom元添加进入动画的核心逻辑就是:通过css给指定元素添加过渡属性,然后使用观察对象监听每个元素,给默认在视口中的元素做最终值的处理,给不在视口中的元素做初始值的处理。那么,当元素进入视口的时候,初始值 -> 最终值 就会应用过渡动画!
图片的懒加载效果(示例)
代码如下:
代码很多,不想看的麻烦,可以直接复制,里面已经写好了注释!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul{
list-style: none;
}
.box{
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.item{
width: calc( 33.33% - 20px );
margin: 10px;
min-height: 200px;
}
.item img{
width: 100%;
}
</style>
</head>
<body>
<div class="box">
<!-- <div class="item">
<img src="./img/Empty.svg" alt="">
</div> -->
</div>
</body>
<script>
//先做一个数组,用来装图片的网络地址
var imgList = [
{
default:'./img/Empty.svg', //这是默认生效的图片,你可以改成自己的
url:'https://images.pexels.com/photos/23719800/pexels-photo-23719800.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/20569931/pexels-photo-20569931.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/23105903/pexels-photo-23105903.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
}
,
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/22816073/pexels-photo-22816073.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/18197764/pexels-photo-18197764.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/24031902/pexels-photo-24031902.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
}
,
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/23914518/pexels-photo-23914518.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/16118941/pexels-photo-16118941.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/22937531/pexels-photo-22937531.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/21915597/pexels-photo-21915597.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/16703290/pexels-photo-16703290.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
}
,
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/13298586/pexels-photo-13298586.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/18109714/pexels-photo-18109714.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/22670156/pexels-photo-22670156.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
}
,
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/21852583/pexels-photo-21852583.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/21367366/pexels-photo-21367366.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/17102067/pexels-photo-17102067.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/24038436/pexels-photo-24038436.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
}
,
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/19473669/pexels-photo-19473669.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/20470948/pexels-photo-20470948.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/22469105/pexels-photo-22469105.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load'
}
,
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/13743557/pexels-photo-13743557.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
},
{
default:'./img/Empty.svg',
url:'https://images.pexels.com/photos/23230661/pexels-photo-23230661.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load'
},
]
var box = document.querySelector('.box');
//渲染页面结构的工具函数,用来遍历list,然后渲染成dom结构到页面
function initImg(list){
for( var i = 0; i < list.length; i++ ){
var div = document.createElement('div');
div.className = 'item';
var img = document.createElement('img');
img.src = list[i].default;
img.dataset.url= list[i].url;
div.appendChild(img);
box.appendChild(div);
}
}
initImg(imgList);//先调用一次工具函数
window.onload = function(){
//这里要等页面加载完毕,也就是默认图片加载完毕后,再执行之后的逻辑
var items = document.querySelectorAll('.item');
Observer(items);//调用观察者工具函数,给其传要观察的Dom对象
}
//观察者工具函数
function Observer(list){
var observer = new IntersectionObserver(function(entries){
for( var n = 0; n < entries.length; n++ ){
if( entries[n].isIntersecting && entries[n].target.children[0].src.includes( "img/Empty.svg" ) ){
entries[n].target.children[0].src = entries[n].target.children[0].dataset.url;
}
}
})
for( var i = 0; i < list.length; i++ ){
observer.observe(list[i])
}
}
</script>
</html>
核心思想:通过src加载一张本地的默认图片,然后通过data-url引入真实的地址。当图片进入视口以后,使用data-url的图片地址,替换src的图片地址。实现图片只有进入视口时才加载的效果。