• 实现一个图片懒加载插件有多难?


    源码地址

    插件完整版地址 m-lazy
    https://github.com/zhanyouwei...

    欢迎一起交流

    欢迎关注我的个人公众号,不定期更新自己的工作心得。
    图片描述

    正文开始

    Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性名)属性的值,并赋予img的src,从而实现动态加载图片的机制。

    这里需要注意的是: img在初始化的时候不要设置src属性,因为即使设置 src='' 浏览器也会尝试加载图片。

    一个简单的图片懒加载共涉及两个方面,

    1. HTML 约定

    我们首先需要给准备实施懒加载的img元素添加指定的class 这里为m-lazyload ,同时将img src赋值给 data-src属性。
    具体示例为:

    <img class="m-lazyload" data-src="imgUrl">

    2. JavaScript 实现

    动态加载总共分为以下几个步骤,这里每个步骤都将被拆分为独立的函数

    1. 添加页面滚动监听事件
    window.addEventListener('scroll', _delay, false);
    
    function _delay() {
      clearTimeout(delay);
      delay = setTimeout(function () {
        _loadImage();
      }, time);
    }
    2. 当触发监听事件时会执行 _loadImage 函数,该函数负责加载图片
    function _loadImage() {
      for (var i = imgList.length; i--;) {
        var el = imgList[i];
        if (_isShow(el)) {
          el.src = el.getAttribute('data-src');
          el.className = el.className.replace(new RegExp("(\s|^)" + _selector.substring(1, _selector.length) + "(\s|$)"), " ");
          imgList.splice(i, 1);
        }
      }
    }

    虽然执行了_loadImage函数,但是我们得知道哪些图片需要被加载,这里的判断依据是什么呢?

    依据就是判断该图片是否在当前窗口的可视区域内,在这里我们封装一个_isShow函数来实现

    function _isShow(el) {
      var coords = el.getBoundingClientRect();
      return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));
    }

    自此一个图片加载的闭环就形成了

    当网页滚动的事件被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。

    太简单了?

    事实就是如此!!!

    如此简单,不妨扩展一下

    1. 添加一些自定义参数,谁都喜欢自定义,不是吗?

    2. 支持iScroll, iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。

    这里我们做了些优化
    1. 图片加载后移除选择器,避免重复判断。

    2. 缓存img元素结合,减少dom元素查询性能损耗

    3. 扩展prototype添加getNode方法,支持分页数据懒加载(由于我们之前缓存了dom元素)

    OK!说了这么多,show me the code 吧!

    
    (function () {
      var imgList = [],  // 页面所有img元素集合
        delay,   // setTimeout 对象
        offset,  //偏移量,用于指定图片距离可视区域多少距离,进行加载
        time,  // 延迟载入时间
        _selector; // 选择器 默认为 .m-lazyload
    
      function _isShow(el) {
        var coords = el.getBoundingClientRect();
        return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));
      }
    
      function _loadImage() {
        for (var i = imgList.length; i--;) {
          var el = imgList[i];
          if (_isShow(el)) {
            el.src = el.getAttribute('data-src');
            el.className = el.className.replace(new RegExp("(\s|^)" + _selector.substring(1, _selector.length) + "(\s|$)"), " ");
            imgList.splice(i, 1);
          }
        }
      }
    
      function _delay() {
        clearTimeout(delay);
        delay = setTimeout(function () {
          _loadImage();
        }, time);
      }
    
      function ImageLazyload(selector, options) {
        var defaults = options || {};
        offset = defaults.offset || 0;
        time = defaults.time || 250;
        _selector = selector || '.m-lazyload';
        this.getNode();
        _delay();//避免首次加载未触发touch事件,主动触发一次加载函数
        if (defaults.iScroll) {
          defaults.iScroll.on('scroll', _delay);
          defaults.iScroll.on('scrollEnd', _delay);
        } else {
          window.addEventListener('scroll', _delay, false);
        }
      }
      ImageLazyload.prototype.getNode = function () {
        imgList = [];
        var nodes = document.querySelectorAll(_selector);
        for (var i = 0, l = nodes.length; i < l; i++) {
          imgList.push(nodes[i]);
        }
      };
    })();
    
  • 相关阅读:
    Yii2中多表关联查询(join、joinwith)
    Yii2.0实用功能技巧解密之——分页功能
    Yii2.0中文开发向导——RBAC(基于角色的访问控制权限)表结构原理分析
    Yii2.0源码分析之——控制器文件分析(Controller.php)创建动作、执行动作
    Yii2.0源码分析之——主题(Theme)
    Yii2.0源码分析之——YiiBase自动加载类、引用文件(autoload)
    MySQL 性能调优的10个方法
    PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询–算法
    ThinkPHP3.2.3验证码显示、刷新、校验
    Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试
  • 原文地址:https://www.cnblogs.com/10manongit/p/12643470.html
Copyright © 2020-2023  润新知