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 相关文章推荐
javascript 动态table添加colspan\rowspan 参数的方法
Jul 25 Javascript
Jquery中删除元素的实现代码
Dec 29 Javascript
Jquery Uploadify多文件上传带进度条且传递自己的参数
Aug 28 Javascript
Jquery取得iframe下内容的方法
Nov 18 Javascript
从零学JS之你需要了解的几本书
May 19 Javascript
Boostrap入门准备之border box
May 09 Javascript
js 判断一组日期是否是连续的简单实例
Jul 11 Javascript
js es6系列教程 - 基于new.target属性与es5改造es6的类语法
Sep 02 Javascript
BootstrapTable加载按钮功能实例代码详解
Sep 22 Javascript
JS表单传值和URL编码转换
Mar 03 Javascript
Vue中使用vux配置代码详解
Sep 16 Javascript
vue-cli 首屏加载优化问题
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 购物车实例(申精)
2009/05/11 PHP
PHP 一个比较完善的简单文件上传
2010/03/25 PHP
基于PHP编程注意事项的小结
2013/04/27 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十五)
2014/06/30 PHP
老司机传授Ubuntu下Apache+PHP+MySQL环境搭建攻略
2016/03/20 PHP
php中array_slice和array_splice函数解析
2016/10/18 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
PHP strripos函数用法总结
2019/02/11 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
Laravel 5.4前后台分离,通过不同的二级域名访问方法
2019/10/13 PHP
php中yii框架实例用法
2020/12/22 PHP
JQUERY获取form表单值的代码
2010/07/17 Javascript
枚举的实现求得1-1000所有出现1的数字并计算出现1的个数
2013/09/10 Javascript
SeaJS入门教程系列之完整示例(三)
2014/03/03 Javascript
js调试工具Console命令详解
2014/10/21 Javascript
JavaScript严格模式详解
2015/11/18 Javascript
基于JS正则表达式实现模板数据动态渲染(实现思路详解)
2020/03/07 Javascript
[02:00]DAC2018主宣传片——龙征四海,剑问东方
2018/03/20 DOTA
[01:31:03]DOTA2完美盛典全回顾 见证十五项大奖花落谁家
2017/11/28 DOTA
python正则表达式去掉数字中的逗号(python正则匹配逗号)
2013/12/25 Python
python抓取京东价格分析京东商品价格走势
2014/01/09 Python
python基础教程之循环介绍
2014/08/29 Python
Python基于递归实现电话号码映射功能示例
2018/04/13 Python
Python之批量创建文件的实例讲解
2018/05/10 Python
Python面向对象之继承和组合用法实例分析
2018/08/27 Python
python pexpect ssh 远程登录服务器的方法
2019/02/14 Python
python如何统计代码运行的时长
2019/07/24 Python
Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现
2020/04/22 Python
基于Python制作一副扑克牌过程详解
2020/10/19 Python
如何用python 操作zookeeper
2020/12/28 Python
保加利亚运动鞋购物网站:SneakerStudio.bg
2020/12/23 全球购物
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
机械设备与数控技术专业求职信
2014/08/10 职场文书
2014年班组工作总结
2014/11/20 职场文书
环卫个人总结
2015/03/03 职场文书
使用pd.merge表连接出现多余行的问题解决
2022/06/16 Python