图片懒加载
方法一:事件监听
监听scroll鼠标滚动事件,鼠标滚动就触发。
需要知道两个高度,一个是窗口显示区的高度,可以用window.innerHeight来获取,其次是图片到视窗上边的距离(高度)可以用元素的getBoundingClientRect().top来获取。
如果图片还未看见,也就是说图片距离视窗顶部的距离大于窗口显示区的高度。
如果图片可以看见,也就是说图片距离视窗顶部的距离小于窗口显示区的高度。
进而问题就转换成了图片是否出现在可视区域内,如果在,就显示图片,反之则不显示
// 获取所有的图片
const images = document.querySelectorAll('img');
window.addEventListener('scoll',(e)=>{
images.forEach(image => {
const imageTop = image.getBoundIngClientRect().top;
if(imageTop < window.innerHeight ){
// 也就是说已经在屏幕内了,所以图片可以开始加载了
const data_src = image.getAttribute('data-src');
image.setAttribute('src',data_src)
}
})
})
但是这样会出现一个问题,就是会频繁出发scroll事件,所以不行。
为什么要使用自定义属性?
如果到了窗口区域,那么图片就准备开始加载,如果用户还没滚动到指定的位置,就不加载图片。使用自定义属性,浏览器碰到这个属性的时候是不会像默认属性那样进行属性处理的,因此我们可以把图片img里的src属性改为data-src,这样就相当于不知道要在哪里下载这些图片了
IntersectionObserver是浏览器提供的构造函数,可以直接拿来使用,但是前提是浏览器能够支持,部分浏览器版本不兼容。
目标元素和可视窗口会产生交叉区域,交叉区域发生了什么事情,我们需要执行什么事情
const images = document.querySelectorAll('img');
const callback = entries => {
entries.forEach( entry => {
if( entry.isIntersecting ){
const image = entry.target;
const data_src = image.getAttribute('data-src');
image.setAttribute('src',data_src);
// 取消观察,避免重复请求
observer.unobserve( image );
}
})
}
const observer = new IntersectionObserver( callback ) // 接收一个回调函数作为参数
images.forEach( image =>{
// 接收所有图片后,对每张图片进行遍历
observer.observe( image )
})