JS图片预加载插件详解


Posted in Javascript onJune 21, 2017

在开发H5项目中有时候会遇到要加载大量图片的情况,利用预加载技术可以提高用户浏览时的体验。

1)概念:

懒加载也叫延迟加载:JS图片延迟加载,延迟加载图片或符合某些条件时才加载某些图片。
预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。

2)区别:

两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

服务器端区别:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。预加载可以说是牺牲服务器前端性能,换取更好的用户体验,这样可以使用户的操作得到最快的反映。

例子:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>preload</title>
  <style>
    * {
      margin: 0;
      pading: 0;
    }

    a {
      text-decoration: none;
    }

    .box {
      text-align: center;
    }

    .btn {
      display: inline-block;
      height: 30px;
      line-height: 30px;
      border: 1px solid #ccc;
      background: #fff;
      padding: 0 10px;
      margin-right: 50px;
      color: #333;
    }

      .btn:hover {
        background: #eee;
      }
    /*进度条样式*/
    .loading {
      position: fixed;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      //撑满整个屏幕 background: #eee;
      text-align: center;
      font-size: 30px;
      font-weight: bold;
    }

    .progress {
      margin-top: 300px;
    }
  </style>
</head>
<body>
  <!--无序预加载需要写进度条,当加载完毕后才能操作;
    有序预加载可以不写进度条,加载完第一张后立即加载第二张、第三张、第四张...
  -->
  <div class="box">
    <img src="http://image.hnol.net/c/2010-11/14/21/201011142147143181-239867.jpg" id="img" alt="pic" width="1000">
    <p>
      <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="btn" data-control="prev">上一张</a>
      <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="btn" data-control="next">下一张</a>
    </p>
  </div>
  <!--进度条-->
  <div class="loading">
    <p class="progress">0%</p>
  </div>
  <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>

  <script src="~/Scripts/preload.js"></script>
  <script>
    var imgs = ['http://image.hnol.net/c/2010-11/14/21/201011142147143181-239867.jpg',
      'http://www.picperweek.com/resource/image/dbc3c16b-5fc6-48e5-aa48-c64739739da2.png',
      'http://imgstore.cdn.sogou.com/app/a/100540002/406526.jpg'],
      index = 0,
      len = imgs.length;
    $progress = $('.progress');
    //有序预加载,可以不用写进度条部分,如果有写,需要手动配置each()、all()方法
    //      $.preload(imgs,{
    //        order:'ordered'
    //      });

    //调用无序预加载  --imgs 数组存放预加载的图片
    $.preload(imgs, {
      //每张图片加载(load事件)一次触发一次each()
      each: function (count) {
        //进度条显示百分比进度
        $progress.html(Math.round((count + 1) / len * 100) + '%');
      },
      //加载完毕
      all: function () {
        $('.loading').hide();
        document.title = '1/' + len;//初始化第一张
      }
    });
    //未封装成插件的无序预加载
    //    $.each(imgs,function(i,src){
    //      var imgObj = new Image();  //Image()实例用于缓存图片
    //
    //      $(imgObj).on('load error',function(){
    //        $progress.html(Math.round((count + 1) / len * 100) + '%');
    //
    //        if(count >= len - 1){
    //          $('.loading').hide();
    //          document.title = '1/' + len;
    //        }
    //        count++;//每加载完一张图片count加1
    //      });
    //
    //      imgObj.src = src;//缓存图片
    //    });
    //上一页,下一页按钮
    $('.btn').on('click', function () {
      if ('prev' === $(this).data('control')) {
        index = Math.max(0, --index);
      } else {
        index = Math.min(len - 1, ++index);
      }
      document.title = (index + 1) + '/' + len;
      $('img').attr('src', imgs[index]);
    });
  </script>
</body>
</html>

插件:

; (function ($) {

  function PreLoad(imgs, options) {
    //保存图片到数组
    this.imgs = (typeof imgs === 'string') ? [imgs] : imgs;
    this.opts = $.extend(PreLoad.defaults, options);

    // this._unordered();//如果只有无序预加载
    if (this.opts.order === 'ordered') {
      this._ordered();
    } else {
      this._unordered();//默认是无序预加载
    }
  };
  PreLoad.defaults = {
    order: 'unordered', //指定默认加载方式为无序
    each: null, //每一张图片加载完毕后执行
    all: null //所有图片加载完毕后执行
  };
  //有序预加载
  PreLoad.prototype._ordered = function () {
    var opts = this.opts,
      imgs = this.imgs,
      len = imgs.length,
      count = 0;

    load();
    function load() {
      var imgObj = new Image();

      $(imgObj).on('load error', function () {
        //相当于if(opts.each){ opts.each(); } ,如果有配置each()方法则调用,后面的all()同理
        opts.each && opts.each(count);

        if (count >= len) {
          //所有图片加载完毕
          opts.all && opts.all();
        } else {
          //如果没加载完,继续调用自身加载下一张
          load();
        }
        count++;
      });

      imgObj.src = imgs[count];//缓存图片
    };
  };

  //无序加载
  PreLoad.prototype._unordered = function () {
    var imgs = this.imgs,
      opts = this.opts,
      count = 0,
      len = imgs.length;

    $.each(imgs, function (i, src) {
      //判断图片数组中的每一项是否为字符串,不是字符串会导致出错,因此返回
      if (typeof src != 'string') return;

      var imgObj = new Image();

      $(imgObj).on('load error', function () {
        //判断opts.each是否存在,不存在则不执行
        opts.each && opts.each(count);

        if (count >= len - 1) {
          //判断opts.all是否存在,存在则执行
          opts.all && opts.all();
        }
        count++;
      });

      imgObj.src = src;//缓存图片
    });
  };

  //由于不用具体的对象去调用,因此用$.extend(object)挂载插件.
  $.extend({
    //preload为插件名
    preload: function (imgs, opts) {
      new PreLoad(imgs, opts);
    }
  });

})(jQuery);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
20个非常棒的Jquery实用工具 国外文章
Jan 01 Javascript
jquery构造器的实现代码小结
May 16 Javascript
jquery 漂亮的删除确认和提交无刷新删除示例
Nov 13 Javascript
ie8下修改input的type属性报错的解决方法
Sep 16 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
Oct 31 Javascript
js中获取jsp表单中radio类型的值简单实例
Aug 15 Javascript
JavaScript之WebSocket技术详解
Nov 18 Javascript
webpack@v4升级踩坑(小结)
Oct 08 Javascript
Angular PWA使用的Demo示例
Jan 31 Javascript
vue-router的钩子函数用法实例分析
Oct 26 Javascript
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
Feb 12 Javascript
详解datagrid使用方法(重要)
Nov 06 Javascript
解决Extjs下拉框不显示的问题
Jun 21 #Javascript
AngularJS解决ng-if中的ng-model值无效的问题
Jun 21 #Javascript
JS 验证密码 不能为空,必须含有数字、字母、特殊字符,长度在8-12位
Jun 21 #Javascript
微信小程序图片宽100%显示并且不变形
Jun 21 #Javascript
微信小程序中页面FOR循环和嵌套循环
Jun 21 #Javascript
微信小程序图片自适应支持多图实例详解
Jun 21 #Javascript
javascript+html5+css3自定义提示窗口
Jun 21 #Javascript
You might like
深入PHP购物车模块功能分析(函数讲解,附源码)
2013/06/25 PHP
php自定义hash函数实例
2015/05/05 PHP
CodeIgniter使用smtp服务发送html邮件的方法
2015/06/10 PHP
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
2007/08/13 Javascript
JavaScript 字符编码规则
2009/05/04 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
js innerHTML 改变div内容的方法
2013/08/03 Javascript
javascript中字符串的定义示例代码
2013/12/19 Javascript
jQuery实现瀑布流布局
2014/12/12 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
jQuery实现的简洁下拉菜单导航效果代码
2015/08/26 Javascript
js jquery获取当前元素的兄弟级 上一个 下一个元素
2015/09/01 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
用jQuery.ajaxSetup实现对请求和响应数据的过滤
2016/12/20 Javascript
使用命令行工具npm新创建一个vue项目的方法
2017/12/27 Javascript
layui使用label标签的方法
2019/09/14 Javascript
微信小程序实现菜单左右联动
2020/05/19 Javascript
vue实现div单选多选功能
2020/07/16 Javascript
将Python的Django框架与认证系统整合的方法
2015/07/24 Python
python的else子句使用指南
2016/02/27 Python
python安装教程 Pycharm安装详细教程
2017/05/02 Python
浅谈flask中的before_request与after_request
2018/01/20 Python
对命令行模式与python交互模式介绍
2018/05/12 Python
Python产生Gnuplot绘图数据的方法
2018/11/09 Python
python 进程 进程池 进程间通信实现解析
2019/08/23 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
浅谈CSS3 动画卡顿解决方案
2019/01/02 HTML / CSS
校园之星获奖感言
2014/01/29 职场文书
社区工作者感言
2014/03/02 职场文书
学校党的群众路线教育实践活动总结材料
2014/10/30 职场文书
起诉意见书范文
2015/05/19 职场文书
2016感恩父亲节主题广播稿
2015/12/18 职场文书
承诺书的签字人,需不需要承担相应的责任?
2019/07/09 职场文书
CSS3新特性详解(五):多列columns column-count和flex布局
2021/04/30 HTML / CSS
vue特效之翻牌动画
2022/04/20 Vue.js