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 相关文章推荐
讲两件事:1.this指针的用法小探. 2.ie的attachEvent和firefox的addEventListener在事件处理上的区别
Apr 12 Javascript
JavaScript 组件之旅(三):用 Ant 构建组件
Oct 28 Javascript
jquery判断浏览器类型的代码
Nov 05 Javascript
对于jQuery性能的一些优化建议
Aug 13 Javascript
js+div实现文字滚动和图片切换效果代码
Aug 27 Javascript
javascript日期验证之输入日期大于等于当前日期
Dec 13 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
Oct 16 Javascript
微信小程序 聊天室简单实现
Apr 19 Javascript
JS实现的简单拖拽购物车功能示例【附源码下载】
Jan 03 Javascript
深入解析vue 源码目录及构建过程分析
Apr 24 Javascript
微信小程序地图实现展示线路
Jul 29 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
Nov 05 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
国产动画《伍六七》原声大碟大卖,啊哈娱乐引领音乐赋能IP的新尝试
2020/03/08 国漫
php实现mysql数据库操作类分享
2014/02/14 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
再谈PHP中单双引号的区别详解
2016/06/12 PHP
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
关于二级域名下使用一级域名下的COOKIE的问题
2011/11/07 Javascript
js实现杯子倒水问题自动求解程序
2013/03/25 Javascript
通过javascript把图片转化为字符画
2013/10/24 Javascript
js实现当前输入框高亮显示的方法
2015/08/19 Javascript
js运动应用实例解析
2015/12/28 Javascript
AngularJS自定义控件实例详解
2016/12/13 Javascript
利用imgareaselect辅助后台实现图片上传裁剪
2017/03/02 Javascript
从setTimeout看js函数执行过程
2017/12/19 Javascript
创建Vue项目以及引入Iview的方法示例
2018/12/03 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
VUE中V-IF条件判断改变元素的样式操作
2020/08/09 Javascript
跟老齐学Python之使用Python操作数据库(1)
2014/11/25 Python
Python paramiko模块的使用示例
2018/04/11 Python
Python实现的多叉树寻找最短路径算法示例
2018/07/30 Python
python调用摄像头拍摄数据集
2019/06/01 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
python中列表的含义及用法
2020/05/26 Python
python程序需要编译吗
2020/06/19 Python
美国知名玩具品牌:Melissa & Doug
2016/08/16 全球购物
SISLEY希思黎官方旗舰店:享誉全球的奢华植物美容品牌
2018/04/25 全球购物
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
教育科研先进个人材料
2014/01/26 职场文书
恐龙的灭绝教学反思
2014/02/12 职场文书
节电标语大全
2014/06/23 职场文书
老人节标语大全
2014/10/08 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
2015年行政部工作总结
2015/04/28 职场文书
2015年乡镇纪委工作总结
2015/05/26 职场文书
springboot @ConfigurationProperties和@PropertySource的区别
2021/06/11 Java/Android