图片懒加载(纯手写)

简介: 图片懒加载(纯手写)

什么是图片懒加载?

默认情况下不加载图片,直到滚动页面,图片进入浏览器窗口的可视区域,才加载图片!

图片懒加载效果预览

image.png

图片懒加载实现原理

图片默认的src属性为空,图片地址存放在data-src属性中,当图片进入可视区域,从data-src属性中取得图片地址,赋值给src属性完成图片的加载

图片懒加载的实现方案

  1. 全局监听浏览器滚动事件
  2. 滚动事件中判断是否有图片进入可视区域
  3. 若图片进入可视区域,则加载图片
  4. 加载图片的过程为:从data-src属性中取得图片地址,赋值给src属性

图片懒加载的完整范例代码

目录结构

index.html

<!DOCTYPE html>
<html>
  <head>
    <title></title>
  </head>
  <body>
    <div style="height: 1000px">
      <img src="./images/1.jpg" />
    </div>
    <div>
      <img class="lazy-element" data-src="./images/2.jpg" />
    </div>
    <div>
      <img class="lazy-element" data-src="./images/3.jpg" />
    </div>
    <div>
      <img class="lazy-element" data-src="./images/4.jpg" />
    </div>

    <script type="text/javascript" src="./lazy.js"></script>
  </body>
</html>

lazy.js

/*  
  图片懒加载的原理:
  图片默认的src属性为空,图片地址存放在data-src属性中
  >> 当图片进入可视区域
  - 从data-src属性中取得图片地址,赋值给src属性完成图片的加载

  图片懒加载的实现方案:
  1. 全局监听浏览器滚动事件
  2. 滚动事件中判断是否有图片进入可视区域
  3. 若图片进入可视区域,则加载图片
  4. 加载图片的过程为:从data-src属性中取得图片地址,赋值给src属性
 */

// 设定懒加载元素的样式名为 lazy-element
let lazyElementClassName = "lazy-element";

// 设定存储图片地址的属性为 data-src
let srcAttrName = "data-src";

// 定义变量--存储浏览器窗口的高度;
let _viewportHeight;
// 定义变量--存储浏览器窗口与页面顶部的距离;
let _pageYOffset;

//   更新浏览器窗口的高度
function setViewportHeight() {
  _viewportHeight =
    window.innerHeight ||
    document.documentElement.clientHeight ||
    document.body.clientHeight;
}

//   更新浏览器窗口与页面顶部的距离
function setPageYOffset() {
  _pageYOffset =
    window.pageYOffset ||
    window.scrollY ||
    document.documentElement.scrollTop ||
    document.body.scrollTop;
}

// 通过 getElementsByClassName 获取所有懒加载元素(数据类型为类似数组的HTMLCollection)
// 使用Array.prototype.slice.call方法将HTMLCollection转化为数组
let elements = Array.prototype.slice.call(
  document.getElementsByClassName(lazyElementClassName)
);

// 设定一个标记 —— 页面是否滚动(默认未滚动)
let initialized = false;

// 初始化浏览器窗口的高度
setViewportHeight();

// 全局监听浏览器滚动事件
window.onscroll = function () {
  // 浏览器滚动时,触发懒加载图片的检测
  scrollEventHandler();
  // 页面滚动时,更新浏览器窗口与页面顶部的距离
  setPageYOffset();
};

// 全局监听浏览器窗口大小改变事件
window.onresize = function () {
  //  浏览器窗口大小改变时,更新浏览器窗口的高度
  setViewportHeight();
};

function scrollEventHandler() {
  // 页面滚动时
  if (!initialized) {
    requestAnimationFrame(function update() {
      // 判断是否加载图片
      checkAvailable();
      // requestAnimationFrame 的回调函数只会被调用一次,如果希望每帧都执行,则每帧都需要调用
      requestAnimationFrame(update);
    });
  }
  // 滚动过后,标记为页面已滚动
  initialized = true;
}

// 判断是否加载图片
function checkAvailable() {
  for (let i = 0; i < elements.length; i++) {
    let el = elements[i];

    // 一旦检测发现进入可视区域
    if (checkElementIsInViewport(el)) {
      // 则加载图片
      loadElement(el);

      // 并将该元素踢出队列
      elements.splice(i--, 1);
    }
  }
}

// 判断元素是否进入可视区域
function checkElementIsInViewport(elem) {
  if (elem.getBoundingClientRect) {
    // getBoundingClientRect方法用于获取元素相对于视口左上方的位移;
    let elemPos = elem.getBoundingClientRect();

    // 元素与视口顶部的距离小于或等于视口高度时,元素进入可视区域
    if (elemPos.top && elemPos.top > 0 && elemPos.top <= _viewportHeight) {
      return true;
    }
    return false;
  } else {
    // 兼容不支持getBoundingClientRect的浏览器
    let offsetTop = getElemOffsetTop(elem);

    // 元素与页面顶部的距离小于或等于视口高度+视口顶部与页面顶部的距离时,元素进入可视区域
    if (
      offsetTop > _pageYOffset &&
      offsetTop < _pageYOffset + _viewportHeight
    ) {
      return true;
    }
    return false;
  }
}

// 获取元素与页面顶部的距离
function getElemOffsetTop(el) {
  let top = el.offsetTop;
  let parent = el.offsetParent;
  while (parent) {
    top += parent.offsetTop || 0;
    parent = parent.offsetParent;
  }
  return top;
}

// 加载图片: 从data-src属性中取得图片地址,赋值给src属性
function loadElement(elem) {
  let srcURL = elem.getAttribute(srcAttrName);
  elem.src = srcURL;
}

目录
相关文章
|
6月前
|
JavaScript
懒加载图片案例
懒加载图片案例
|
存储 前端开发 JavaScript
前端实现图片的懒加载
前端实现图片的懒加载
64 0
|
3月前
|
存储 JavaScript UED
图片懒加载
图片懒加载
|
3月前
|
JavaScript API
如何实现图片懒加载
如何实现图片懒加载
72 0
|
6月前
|
JavaScript 前端开发
如何实现网页的懒加载?图片懒加载的原理
如何实现网页的懒加载?图片懒加载的原理
46 0
|
11月前
|
存储
图片懒加载(二)
图片懒加载(二)
47 1
|
前端开发
前端学习案例2-图片懒加载2
前端学习案例2-图片懒加载2
57 0
前端学习案例2-图片懒加载2
|
JavaScript 前端开发 UED
实现图片懒加载(及优化相关)
工作之余想要休闲一下(看-美-女-图),但是又觉得单纯休闲不利于自身进步,于是 ……
实现图片懒加载(及优化相关)
图片懒加载的底层原理是什么?
图片懒加载的底层原理是什么?