JS图片懒加载

实现方式一:

原理:

  1. 先设置图片的data-src属性(浏览器不会加载data-*属性)。
  2. 获取图片距离顶部的高度和整个屏幕的高度,若是小于关系,说明图片进入了可视窗口,则设置图片的src属性。

代码:

<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<img src="" alt="" data-src="./images/iPhone.jpg">
<img src="" alt="" data-src="./images/iPhone.jpg">
<img src="" alt="" data-src="./images/iPhone.jpg">
<img src="" alt="" data-src="./images/iPhone.jpg">
<img src="" alt="" data-src="./images/iPhone.jpg">
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
<p>111111111111111111111111111111</p>
const images = document.querySelectorAll('img')
window.addEventListener('scroll',e => {
    images.forEach(item => {
        const itemTop = item.getBoundingClientRect().top
        if(itemTop < window.innerHeight){
            const data_src = item.getAttribute('data-src')
            item.setAttribute('src',data_src)
        }
        console.log('滚动');
    })
})

缺点:

  1. 打印滚动次数过多
  2. 需要增加滚动事件监听

优化:

使用节流(n秒内只运行一次,若在n 秒后重复执行,只有一次执行 )进行优化。

const images = document.querySelectorAll('img')
window.addEventListener('scroll',throttle(e => {
    images.forEach(item => {
        const itemTop = item.getBoundingClientRect().top
        if(itemTop < window.innerHeight){
            const data_src = item.getAttribute('data-src')
            item.setAttribute('src',data_src)
        }
    })
    console.log('滚动');
},2000))  

function throttle(fn,t){
    let last,timer
    let interval = t | 500
    return function(){
        let args = arguments
        let now = +new Date()
        if(last && now - last < interval){
            clearTimeout(timer)
            timer = setTimeout(()=>{
                last = now
                fn.apply(this,args)
            },interval)
        }else{
            last = now
            fn.apply(this,args)
        }
    }
}

但是,尽管做了优化,图片展示了滚动事件还是会继续监听,所以得使用另一种实现方式:IntersectionObserver。

实现方式二:

IntersectionObserver是浏览器提供的函数,需要浏览器支持。

原理:

  1. 先拿到所有的img DOM节点
  2. 对这个构造方法进行实例化
  3. 使用forEach对每一个图片进行观察
  4. 这个构造方法接收一个回调函数,回调函数触发两次,回调函数有一个参数entries(是观察对象组成的一个数组),每个观察对象有一个isIntersecting属性,代表是否进入可视区域。
  5. 进入可视区域就把data-src属性赋值于src属性,因为图片已经显示了,没有必要继续观察,使用unobserve方法关闭观察。
    在这里插入图片描述

代码:

let images = document.querySelectorAll('img')
console.log(images);
function lazyLoad(entries){
    entries.forEach(item => {
        if(item.isIntersecting){
            const image = item.target
            const data_src = image.getAttribute('data-src')
            image.setAttribute('src',data_src)
            o.unobserve(image)
            console.log('触发');
        }
    })
}

let o = new IntersectionObserver(lazyLoad) 

images.forEach(item => {
    o.observe(item)
})

使用IntersectionObserver方法,可以对已显示的图片不再进行监听,大大提升了原始方法的性能。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值