js图片加载效果实例代码(延迟加载+瀑布流加载)


Posted in Javascript onMay 12, 2017

主要做了两种图片加载的效果

一种是遇到页面图片比较多的时候,带读条效果的加载提示(为了验证正确加载,设置了1秒钟的加载间隔时间)

另外一种是根据滑块的位置进行图片的预加载,在用户不察觉的情况下,实现瀑布流的加载效果

一 延迟加载

主要思路:

  1. HTML的img标签中,将正确的地址存在data-src属性中,给所有图片设置一个转圈圈的loading图片作为background
  2. js中,依次读取每一个img,将data-src中的地址替换到src中,去掉background
  3. 每成功加载一张图片,进度条的百分比进行相应的变化。
  4. 如果加载不成功,就提示图片加载错误。

HTML结构很简单,就是一个div.picList包裹了所有img,然后加上一个简单的进度条div#loadBar

<body>
  <div class="picList">
    <img class="lazy" data-src="pic/compressed/picList1.jg">
    <img class="lazy" data-src="pic/compressed/picList2.jpg">
    <img class="lazy" data-src="pic/compressed/picList3.jpg">
    <img class="lazy" data-src="pic/compressed/picList4.jpg">
    <img class="lazy" data-src="pic/compressed/picList5.jpg">
    <img class="lazy" data-src="pic/compressed/picList6.jpg">
    <img class="lazy" data-src="pic/compressed/picList7.jpg">
    <img class="lazy" data-src="pic/compressed/picList8.jpg">
    <img class="lazy" data-src="pic/compressed/picList9.jpg">
    <img class="lazy" data-src="pic/compressed/picList10.jpg">
  </div>

  <div id="loadBar">
    <div id="loadBarMask"></div>
  </div>
</body>

css(使用的scss,编译时会自动加上各种兼容前缀)

.picList{
  img{
    width: 100px;
    height: 100px;
    position: relative;

    /*加载失败时显示灰底文字*/
    &:after{
      content: "( ⊙ o ⊙ )加载失败";
      font-size: 6px;
      font-family: FontAwesome;
      color: rgb(100, 100, 100);
      display: flex;
      justify-content: center;
      align-items: center;
      position: absolute;
      top: 0;
      left: 0;
      width: 100px;
      height: 100px;
      background-color: #ddd;
    }
  }
}

.lazy{
  background: url(../pic/loading.gif) center no-repeat;
  border: 1px solid black;
}

#loadBar{
  width: 200px;
  height: 15px;
  background: linear-gradient(90deg,#187103,#81b50b,#187103);
  border: 10px solid white;

  position: absolute;
  top: 150px;
  left: 50%;
  margin-left: -100px;

  #loadBarMask{
    width: 70%;//这个数值显示没有加载成功的图片
    height: 100%;
    background-color: beige;
    position: absolute;
    right: 0;
  }
}

css里面需要注意的地方有两个:

  1. 一个是把图片加载错误时显示的灰底文字放在了img的after伪类中,当图片加载失败,又去掉了background的gif图片之后,就会显示这个部分的内容及样式。
  2. 一个是进度条的样式。写得很简单,主要是一层带渐变的绿色和一层白色叠在一起。绿色表示已加载,白色表示未加载。显示的时候,直接控制白色那层的宽度即可。

js部分(直接执行loadPicPerSecond()即可)

var lazyPic = $('img.lazy');
var loadBarMask = $('#loadBarMask');
var picList = $('.picList');

var activePic = 0;
var totalPic = lazyPic.length;

/*每秒加载一张图片*/

function loadPicPerSecond(){

  lazyPic.each(function(index){

    var self = $(this);

    //console.log(self[0].complete);
    /*img标签已经事先写在html中,所以此时的complete状态全部都是true*/

    setTimeout(function(){

      src[index] = self.attr('data-src');
      self.attr('src',src[index]);
      self.removeClass('lazy');

      //图片获得正确src地址之后,可以执行下面的onload操作
      self[0].onload = function(){

        //加载读条loadBar动画
        countPic();
      }

      //图片获得的src地址不正确时,执行下面的onerror操作
      self[0].onerror = function(){
        /*this.style.background = 'url(pic/compressed/picList18.jpg) center no-repeat';*/
        countPic();
      }

    },1000*index);

  })

}

/*根据onload的执行情况来计算当前的图片加载进度.每onload一次,activePic就增加1*/

function countPic(){

  activePic++;

  var leftPic = totalPic - activePic;
  var percentPic = Math.ceil(leftPic/totalPic*100);//没有加载的图片百分比,和loadBarMask的宽度占比配合

  console.log("已加载"+(100-percentPic)+"%");

  loadBarMask.css("width",percentPic+"%");

  if(percentPic==0){
    $('#loadBar').hide();
  }
}

二 瀑布流加载

主要思路:

  1. 监听窗口滚动情况,当已经加载的图片的最后一张快要进入窗口的时候,开始加载下面的图片。
  2. 假设所有的图片地址已经存在一个json数据中,每次读取10张图片地址,加载它们之后,插入到现有的瀑布流末尾。
  3. 如此往复,直到加载完所有图片。

HTML和前面部分相同,只是把src写成正常地址即可。css完全一样。

js部分

var lazyPic = $('img.lazy');
var loadBarMask = $('#loadBarMask');
var picList = $('.picList');

var scrollTop,
  clientHeight,
  scrollHeight;

var threshold = 200; //最后一张图片距离窗口200px的时候开始加载图片

var src = [];

var activePic = 0;
var totalPic = lazyPic.length;

//待加载的图片数据
var dirtSrc = "pic/compressed/picList";
var picData = {imgSrc:[
  dirtSrc + "20.jpg",
  dirtSrc + "21.jpg",
  dirtSrc + "22.jpg",
  dirtSrc + "23.jpg",
  dirtSrc + "24.jpg",
  dirtSrc + "25.jpg",
  dirtSrc + "26.jpg",
  dirtSrc + "27.jpg",
  dirtSrc + "28.jpg",
  dirtSrc + "29.jpg",
  dirtSrc + "30.jpg",
  dirtSrc + "31.jpg",
  dirtSrc + "32.jpg",
  dirtSrc + "33.jpg",
  dirtSrc + "34.jpg",
  dirtSrc + "35.jpg",
  dirtSrc + "36.jpg",
  dirtSrc + "37.jpg",
  dirtSrc + "38.jpg",
  dirtSrc + "39.jpg",
  dirtSrc + "40.jpg",
  dirtSrc + "41.jpg",
  dirtSrc + "42.jpg",
  dirtSrc + "43.jpg",
  dirtSrc + "44.jpg",
  dirtSrc + "45.jpg",
  dirtSrc + "46.jpg",
  dirtSrc + "47.jpg",
  dirtSrc + "48.jpg",
  dirtSrc + "49.jpg",
]};

//加载次数计数器
var scrollIndex = 0;

$(function(){

  /*监听窗口滚动情况*/
  $(window).on('scroll',function(){

    scrollTop = $(window).scrollTop();//$(window).scrollTop()==document.body.scrollTop
    clientHeight = $(window).height();
    scrollHeight = picList.last().height();//picList.last()[0].clientHeight

    /*目标与窗口的距离达到阈值时开始加载*/
    if(scrollHeight-clientHeight-scrollTop < threshold){
      scrollPic(10);
    }
  })
})

/*根据滚动程度加载图片,每次加载perAmount张*/

function scrollPic(perAmount = 10){

  var totalAmount = perAmount * (scrollIndex+1);

   //考虑到最后一次加载的时候,剩余的图片数量有可能达不到限定的每次加载的数量,这时候需要更改totalAmount的值
  if(totalAmount>picData.imgSrc.length){
    totalAmount = picData.imgSrc.length;
  }
  for(scrollIndex;scrollIndex<totalAmount;scrollIndex++){
    var oimg = new Image();
    oimg.src = picData.imgSrc[scrollIndex];
    picList.append(oimg);
  }

}

比较捉急的就是scrollTop、height那几个值的取值对象,总是记不清楚,所以按照js和jquery都写上了,以后可以直接用。将数值关系搞定之后,只要满足条件就触发加载即可。

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

Javascript 相关文章推荐
用htc组件制作windows选项卡
Jan 13 Javascript
防止动态加载JavaScript引起的内存泄漏问题
Oct 08 Javascript
jquery 弹出层注册页面等(asp.net后台)
Jun 17 Javascript
script标签的 charset 属性使用说明
Dec 04 Javascript
jquery阻止冒泡事件使用模拟事件
Sep 06 Javascript
Javscript调用iframe框架页面中函数的方法
Nov 01 Javascript
node.js中的console.info方法使用说明
Dec 09 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
May 18 Javascript
jquery实现简单合拢与展开网页面板的方法
Sep 01 Javascript
分享一个精简的vue.js 图片lazyload插件实例
Mar 13 Javascript
详解使用fetch发送post请求时的参数处理
Apr 05 Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
Apr 25 Javascript
微信小程序之数据双向绑定与数据操作
May 12 #Javascript
Flask中获取小程序Request数据的两种方法
May 12 #Javascript
关于bootstrap日期转化,bootstrap-editable的简单使用,bootstrap-fileinput的使用详解
May 12 #Javascript
微信小程序 支付功能实现PHP实例详解
May 12 #Javascript
深入理解JavaScript继承的多种方式和优缺点
May 12 #Javascript
JS实现图片预加载之无序预加载功能代码
May 12 #Javascript
详解React开发中使用require.ensure()按需加载ES6组件
May 12 #Javascript
You might like
一个基于PDO的数据库操作类
2011/03/24 PHP
Server.HTMLEncode让代码在页面里显示为源代码
2013/12/08 PHP
Yii2框架实现利用mpdf创建pdf文件功能示例
2019/02/08 PHP
HTML Dom与Css控制方法
2010/10/25 Javascript
javaScript(JS)替换节点实现思路介绍
2013/04/17 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
jquery.mobile 共同布局遇到的问题小结
2015/02/10 Javascript
深入理解JavaScript系列(39):设计模式之适配器模式详解
2015/03/04 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
2015/06/12 Javascript
详解webpack3如何正确引用并使用jQuery库
2017/08/26 jQuery
原生js实现form表单序列化的方法
2018/08/02 Javascript
Bootstrap的aria-label和aria-labelledby属性实例详解
2018/11/02 Javascript
关于angular浏览器兼容性问题的解决方案
2020/07/26 Javascript
解决Mint-ui 框架Popup和Datetime Picker组件滚动穿透的问题
2020/11/04 Javascript
小程序自定义圆形进度条
2020/11/17 Javascript
[38:31]完美世界DOTA2联赛PWL S3 Magma vs GXR 第一场 12.13
2020/12/17 DOTA
详解Python中的正则表达式的用法
2015/04/09 Python
使用pygame模块编写贪吃蛇的实例讲解
2018/02/05 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
详解Python给照片换底色(蓝底换红底)
2019/03/22 Python
Python实现自动访问网页的例子
2020/02/21 Python
Python修改列表值问题解决方案
2020/03/06 Python
Python通过4种方式实现进程数据通信
2020/03/12 Python
Virtualenv 搭建 Py项目运行环境的教程详解
2020/06/22 Python
Python txt文件常用读写操作代码实例
2020/08/03 Python
css3的@media属性实现页面响应式布局示例代码
2014/02/10 HTML / CSS
美国杂志订阅折扣与优惠网站:Magazines.com
2016/08/31 全球购物
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
美国在线家具网站:GDFStudio
2021/03/13 全球购物
医科大学毕业生自荐信
2014/02/03 职场文书
承诺书的格式范文
2014/03/28 职场文书
2014年宣传部个人工作总结
2014/12/06 职场文书
2019银行竞聘书
2019/06/21 职场文书
oracle DGMGRL ORA-16603报错的解决方法(DG Broker)
2021/04/06 Oracle
Java面试题冲刺第十六天--消息队列
2021/08/07 面试题
为什么MySQL 删除表数据 磁盘空间还一直被占用
2021/10/16 MySQL