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 相关文章推荐
基于jquery的用鼠标画出可移动的div
Sep 06 Javascript
ExtJS4中的requires使用方法示例介绍
Dec 03 Javascript
Javascript实现简单的富文本编辑器附演示
Jun 16 Javascript
基于jQuery实现自动轮播旋转木马特效
Nov 02 Javascript
Jquery插件easyUi实现表单验证示例
Dec 15 Javascript
JavaScript代码实现左右上下自动晃动自动移动
Apr 08 Javascript
AngularJS过滤器filter用法实例分析
Nov 04 Javascript
微信小程序 require机制详解及实例代码
Dec 14 Javascript
BootStrap 动态表单效果
Jun 02 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
Jan 16 Javascript
vue-router重定向不刷新问题的解决
Jun 25 Javascript
Vue项目中使用better-scroll实现菜单映射功能方法
Sep 11 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
预告映像公开!第1章续篇剧场版动画《Princess Principal Crown Handler》4月10日上映!
2020/03/06 日漫
php读取目录及子目录下所有文件名的方法
2014/10/20 PHP
详解PHP错误日志的获取方法
2015/07/20 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
2019/05/01 PHP
分享27个jQuery 表单插件集合推荐
2011/04/25 Javascript
jquery中.add()的使用分析
2013/04/26 Javascript
js控制不同的时间段显示不同的css样式的实例代码
2013/11/04 Javascript
javascript禁用Tab键脚本实例
2013/11/22 Javascript
node.js中的buffer.write方法使用说明
2014/12/10 Javascript
node.js中的fs.writeFileSync方法使用说明
2014/12/14 Javascript
JavaScript代码性能优化总结(推荐)
2016/05/16 Javascript
原生js验证简洁注册登录页面
2016/12/17 Javascript
BootStrap 图片样式、辅助类样式和CSS组件的实例详解
2017/01/20 Javascript
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
利用vue和element-ui设置表格内容分页的实例
2018/03/02 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
vue实现登录页面的验证码以及验证过程解析(面向新手)
2019/08/02 Javascript
jQuery Raty星级评分插件使用方法实例分析
2019/11/25 jQuery
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
[05:17]DOTA2睡衣妹卖萌求签名 CJ第二天全明星影像
2013/07/28 DOTA
[01:41]DOTA2超级联赛专访YYF 称一辈子难忘TI2
2013/05/28 DOTA
[00:27]DOTA2战队VP、Secret贺新春
2018/02/11 DOTA
[00:36]我的中国心——Serenity vs Fnatic
2018/08/21 DOTA
用于统计项目中代码总行数的Python脚本分享
2015/04/21 Python
python 打印出所有的对象/模块的属性(实例代码)
2016/09/11 Python
python3.5+tesseract+adb实现西瓜视频或头脑王者辅助答题
2018/01/17 Python
PyQt5每天必学之布局管理
2018/04/19 Python
python3 拼接字符串的7种方法
2018/09/12 Python
使用Pyhton集合set()实现成果查漏的例子
2019/11/24 Python
Python concurrent.futures模块使用实例
2019/12/24 Python
Python函数式编程实例详解
2020/01/17 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
地球鞋加拿大官网:Earth Shoes Canada
2020/11/17 全球购物
linux面试相关问题
2012/08/11 面试题
介绍一下Ruby的特点
2013/01/20 面试题
微信营销策划方案
2014/02/24 职场文书