图片懒加载

监听滚动事件和IntersectionObserver()实现图片懒加载

图片懒加载

1
2
3
4
5
6
7
8
9
10
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<img data-src="1.jpg" />
<img data-src="2.jpg" />
<img data-src="3.jpg" />
<img data-src="4.jpg" />
<img data-src="5.jpg" />
<img data-src="6.jpg" />

一、 监听滚动事件,判断图片与视口的高度差来重置图片的src

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const imgs = document.querySelectorAll('img');

function lazyLoad(){
imgs.forEach( (img) => {
// 获取每个图片的距离文档顶部的位置
const imageTop = img.getBoundingClientRect().top;
// 图片位置高于视口高度时,重置src属性
if(imageTop < window.innerHeight){
// 将图片的data-src属性赋值给src属性
const data_src = img.getAttribute('data-src');
img.setAttribute('src', data_src)
}
})
}

// 防抖
function debounce(fn, delay = 500) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this, args);
}, delay);
};
}

//屏幕添加滚动事件监听
window.addEventListener('scroll', debounce(lazyLoad, 600))

缺点:

  1. 屏幕滚动的时候会不断触发滚动事件
  2. 图片加载完成之后,当触发滚动事件,还会不断更新src的值

二、 IntersectionObserver()方法监听或取消监听图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const imgs = document.querySelectorAll('img');

// 3. 回调函数的参数是一个数组,数组内容为监听内容的集合;
const callback = ( entries ) => {
console.log( entries );
entries.forEach( entry => {
// 当元素的isIntersecting为true时表示监听到图片内容
if (entry.isIntersecting) {
const img = entry.target;
const data_src = img.getAttribute('data-src');
img.setAttribute('src', data_src);
// 图片加载后就取消监听,避免时候视口滚动重复加载
observer.unobserve(img);
// 核实图片加载时机和次数
console.log('666');
}
})
}

// 1. 创建IntersectionObserver实例,提供一种异步观察目标元素与其祖先或顶级视窗交叉状态的方法,参数是一个回调函数
const observer = new IntersectionObserver( callback );

// 2. 遍历图像数组,监听每个图像
imgs.forEach( img => {
observer.observe(img)
})

缺点:

  1. 兼容性 不支持ie

优点:

  1. 每个懒加载图片只加载一次