前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript实现图片懒加载(lazyload)

JavaScript实现图片懒加载(lazyload)

原创
作者头像
伯爵
修改2019-10-24 14:33:31
9830
修改2019-10-24 14:33:31
举报
文章被收录于专栏:前端小菜鸟

图片懒加载可以减少不必要的图片资源请求,提高页面的加载速度,提升用户体验。我们实现页面懒加载的方案一般有三种方式:

  • 获取元素clientHeight等位置信息
  • Element.getBoundingClientRect()
  • IntersectionObserver

我们先写HTML的DOM结构:

代码语言:txt
复制
<style>
ul, li {
    margin: 0px;
    list-style: none;
}
li {
    height: 500px;
}
img {
    width: 1000px;
    height: 100%;
}

</style>

<ul id="lazyload">
    <li>
        <img data-src="./images/1.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/2.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/3.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/4.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/5.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/6.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/7.png" alt="loading">
    </li>
    <li>
        <img data-src="./images/8.png" alt="loading">
    </li>
</ul>

完全加载

在懒加载优化之前,我们使用全部加载的伪代码,根据islazyLoadBool()方法判断对应的懒加载逻辑。在实际开发过程中回去涉及到节流请求等操作。

代码语言:txt
复制
let imgList = document.querySelectorAll('#lazyload img') || [];
let clientHeight = window.innerHeight;
loadimgListener();
window.onscroll = this.loadimgListener;

//图片加载监听器
function loadimgListener() {
  Array.from(imgList).forEach(dom => {
    islazyLoadBool(dom) && loadImg(dom);
  })
}

//加载图片
function loadImg(img) {
    if(!img || img.src) return;
    img.src = img.getAttribute('data-src');
}

function islazyLoadBool(dom) {
    return true; //TODO:懒加载核心:判断加载
}

clientHeight,offsetTop,scrollTop等位置信息

我们首先了解常见的DOM元素位置属性:

代码语言:txt
复制
let dom = document.body;

dom.clientHeight; //可见区域高度
dom.clientTop; //可见区域左边距
dom.offsetHeight; //可见区域左边距-带边框
dom.scrollTop;// 被隐藏的顶部
window.screen.height // 屏幕高度

我们的核心是根据图片的位置判断是否加载:

代码语言:txt
复制
//判断加载
function islazyLoadBool(dom) {
  let imgTop = dom.offsetTop; //获取响度浏览器可视区的高度
  let srcollTop = document.documentElement.scrollTop || document.body.scrollTop; 
  return imgTop <= clientHeight + srcollTop ;
}

Element.getBoundingClientRect()

Element.getBoundingClientRect() 返回一个DOMRect对象,包含了描述元素的位置属性:left,right,top,bottom。rectObject = object.getBoundingClientRect();

我们可以使用定时器或者scroll事件,在回调函数调用元素的getBoundingClientRect()方法,获取元素的位置。

代码语言:txt
复制
//懒加载核心:判断加载
function islazyLoadBool(dom) {
  let imgTop = dom.getBoundingClientRect().top; //获取响度浏览器可视区的高度
  let srcollTop = document.documentElement.scrollTop || document.body.scrollTop; 
  return imgTop <= clientHeight + 100 ;
}

因为getBoundingClientRect()会强制重新计算元素布局,所以这个方法存在一定的性能隐患,不建议使用。

IntersectionObserver

IntersectionObserver 提供异步接口监听目标元素与其祖先元素(或者视窗viewport),

IntersectionObserver API 可以用来实现图片懒加载功能,在不支持该API的浏览器使用 polyfill

代码语言:txt
复制
// 加载图片
function loadImg(ele) {
    let target = ele && ele.target;
    target.src = target.dataset.src;
    console.log(target.src)
}

function callback (arr) {
    arr.forEach(item => {
        if(item.isIntersecting) {
            loadImg(item);
            io.unobserve(item.target)
        }
    })
}

var io = new IntersectionObserver(callback);

let imgs = document.querySelectorAll('img');
imgs.forEach(item => {
    io.observe(item);
})

参考

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完全加载
  • clientHeight,offsetTop,scrollTop等位置信息
  • Element.getBoundingClientRect()
  • IntersectionObserver
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档