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 相关文章推荐
利用a标签自动解析URL分析网址实例
Oct 20 Javascript
jquery点击缩略图切换视频播放特效代码分享
Sep 15 Javascript
纯js实现手风琴效果
Apr 17 Javascript
浅析函数声明和函数表达式——函数声明的声明提前
May 03 Javascript
深入理解vue路由的使用
Mar 24 Javascript
JS实现针对给定时间的倒计时功能示例
Apr 11 Javascript
JavaScript变量类型以及变量作用域详解
Aug 14 Javascript
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
Vue.js单向绑定和双向绑定实例分析
Aug 14 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
Oct 08 Javascript
ajaxfileupload.js实现上传文件功能
Apr 19 Javascript
vue-cli4.0多环境配置变量与模式详解
Dec 30 Vue.js
解决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
第六节--访问属性和方法
2006/11/16 PHP
剖析 PHP 中的输出缓冲
2006/12/21 PHP
PHP关联链接常用代码
2012/11/05 PHP
PHP快速排序quicksort实例详解
2016/09/28 PHP
Symfony2获取web目录绝对路径、相对路径、网址的方法
2016/11/14 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
js数组中如何随机取出一个值
2014/06/13 Javascript
JavaScript中的闭包介绍
2015/03/15 Javascript
微信小程序 PHP后端form表单提交实例详解
2017/01/12 Javascript
原生js实现秒表计时器功能
2017/02/16 Javascript
bootstrap paginator分页插件的两种使用方式实例详解
2017/11/14 Javascript
jQuery实现表单动态加减、ajax表单提交功能
2018/06/08 jQuery
node使用mysql获取数据库数据中文乱码问题的解决
2019/12/02 Javascript
解决vue-cli输入命令vue ui没效果的问题
2020/11/17 Javascript
Python算术运算符实例详解
2017/05/31 Python
python实现图书馆研习室自动预约功能
2018/04/27 Python
对python mayavi三维绘图的实现详解
2019/01/08 Python
Python时间序列处理之ARIMA模型的使用讲解
2019/04/02 Python
django自带serializers序列化返回指定字段的方法
2019/08/21 Python
Python多线程模块Threading用法示例小结
2019/11/09 Python
PYcharm 激活方法(推荐)
2020/03/23 Python
使用keras和tensorflow保存为可部署的pb格式
2020/05/25 Python
Python操作dict时避免出现KeyError的几种解决方法
2020/09/20 Python
Python中pass的作用与使用教程
2020/11/13 Python
css3学习之2D转换功能详解
2016/12/23 HTML / CSS
三星俄罗斯授权在线商店:Samsung俄罗斯
2019/09/28 全球购物
.NET常见笔试题集
2012/12/01 面试题
工厂门卫岗位职责
2013/11/25 职场文书
护士自我鉴定怎么写
2014/02/07 职场文书
人力资源管理求职信
2014/08/07 职场文书
党的群众路线教育实践活动对照检查剖析材料
2014/10/09 职场文书
工程进度款催款函
2015/06/24 职场文书
医院保洁员管理制度
2015/08/05 职场文书
《小小的船》教学反思
2016/02/18 职场文书
八年级作文之一起的走过日子
2019/09/17 职场文书
CSS中使用grid布局实现一套模板多种布局
2022/07/15 HTML / CSS