JS实现图片懒加载的三种方式

实现思路

将页面中的img标签src指向一张小图片或者src为空,然后定义data-src(这个属性可以自定义命名,我才用data-src)属性指向真实的图片
通过js判断页面是否滚动到某张图片需要显示的位置,这时将src赋值为data-src

offsetTop方式

图片距离页面顶部的高度 < 浏览器可视高度 + 滚动条距离页面顶部的高度: offsetTop < clientHeight + scrollTop

const imgs = document.querySelectorAll('img')
const num = imgs.length;
let n = 0; // 当前图片已加载的位置
const lazyload = () => {
    const clientHeight = document.documentElement.clientHeight; // 可见区域高度
    const scrollTop = document.documentElement.scrollTop;  // 滚动条距离顶部高度
    for (let i = n; i < num; i++) {
        if (imgs[i].offsetTop < clientHeight + scrollTop) { // 当前浏览器所在距离 > 图片距离顶部的距离时加载
            if (imgs[i].getAttribute("src") == "") {
                imgs[i].src = imgs[i].getAttribute("data-src");
            }
            n = i + 1;
        }
    }
}
lazyload();
window.onscroll = lazyload;

getBoundingClientRect方式

图片上边距离到可视区上边的距离(可为负数) < 浏览器可视高度: element.getBoundingClientRect().top < clientHeight
在这里插入图片描述

h5的IntersectionObserver方式

intersectionRatio:目标元素的可见比例,即 intersectionRect 占 boundingClientRect 的比例,完全可见时为 1 ,完全不可见时小于等于 0

function getTag(tag) {
    return Array.from(document.getElementsByTagName(tag));
}
var observer = new IntersectionObserver(
    (changes) => {
        changes.forEach((change) => {
            if (change.intersectionRatio > 0) {
                var img = change.target;
                img.src = img.dataset.src;
                observer.unobserve(img);
            }
        })
    }
)
getTag('img').forEach((item) => {
    observer.observe(item);
})

优化

通过以下css可以提高性能

  # 之所以使用visibility而不是display是因为
  # visibility不会触发重绘(repaint)和重排(reflow)
  img {
    visibility: hidden;
  }
  
  img[src] {
    visibility: visible;
  }

因为scroll事件的触发频率很高,频繁操作dom结点会造成很大的性能问题,所以需要做节流和防抖设计,减少scroll事件的触发频率

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值