概述

两种图片加载的效果:一种是遇到图片较多时,带读条效果的加载提示;另一种是根据滑块的位置进行预加载,用户不察觉的情况下,实现瀑布流的加载效果

详细

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

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

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

一、延迟加载

1、需要准备什么环境

2、需要开通什么服务,如果有的话

3、本例子实现什么功能

二、程序实现

主要思路:

  1. HTML的img标签中,将正确的地址存在data-src属性中,给所有图片设置一个转圈圈的loading图片作为background

  2. js中,依次读取每一个img,将data-src中的地址替换到src中,去掉background

  3. 每成功加载一张图片,进度条的百分比进行相应的变化。

  4. 如果加载不成功,就提示图片加载错误。


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

  1. <body>
  2. <div class="picList">
  3. <img class="lazy" data-src="pic/compressed/picList1.jg">
  4. <img class="lazy" data-src="pic/compressed/picList2.jpg">
  5. <img class="lazy" data-src="pic/compressed/picList3.jpg">
  6. <img class="lazy" data-src="pic/compressed/picList4.jpg">
  7. <img class="lazy" data-src="pic/compressed/picList5.jpg">
  8. <img class="lazy" data-src="pic/compressed/picList6.jpg">
  9. <img class="lazy" data-src="pic/compressed/picList7.jpg">
  10. <img class="lazy" data-src="pic/compressed/picList8.jpg">
  11. <img class="lazy" data-src="pic/compressed/picList9.jpg">
  12. <img class="lazy" data-src="pic/compressed/picList10.jpg">
  13. </div>
  14.  
  15. <div id="loadBar">
  16. <div id="loadBarMask"></div>
  17. </div>
  18. </body>

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

  1. .lazy{
  2. background: url(../pic/loading.gif) center no-repeat;
  3. border: 1px solid black;
  4. }
  5.  
  6. #loadBar{
  7. width: 200px;
  8. height: 15px;
  9. background: linear-gradient(90deg,#187103,#81b50b,#187103);
  10. border: 10px solid white;
  11.  
  12. position: absolute;
  13. top: 150px;
  14. left: 50%;
  15. margin-left: -100px;
  16.  
  17. #loadBarMask{
  18. width: 70%;//这个数值显示没有加载成功的图片
  19. height: 100%;
  20. background-color: beige;
  21. position: absolute;
  22. right: 0;
  23. }
  24. }

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

  • 一个是把图片加载错误时显示的灰底文字放在了img的after伪类中,当图片加载失败,又去掉了background的gif图片之后,就会显示这个部分的内容及样式。

  • 一个是进度条的样式。写得很简单,主要是一层带渐变的绿色和一层白色叠在一起。绿色表示已加载,白色表示未加载。显示的时候,直接控制白色那层的宽度即可。

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

  1. var lazyPic = $('img.lazy');
  2. var loadBarMask = $('#loadBarMask');
  3. var picList = $('.picList');
  4.  
  5. var activePic = 0;
  6. var totalPic = lazyPic.length;
  7.  
  8. /*每秒加载一张图片*/
  9.  
  10. function loadPicPerSecond(){
  11.  
  12. lazyPic.each(function(index){
  13.  
  14. var self = $(this);
  15.  
  16. //console.log(self[0].complete);
  17. /*img标签已经事先写在html中,所以此时的complete状态全部都是true*/
  18.  
  19. setTimeout(function(){
  20.  
  21. src[index] = self.attr('data-src');
  22. self.attr('src',src[index]);
  23. self.removeClass('lazy');
  24.  
  25. //图片获得正确src地址之后,可以执行下面的onload操作
  26. self[0].onload = function(){
  27.  
  28. //加载读条loadBar动画
  29. countPic();
  30. }
  31.  
  32. //图片获得的src地址不正确时,执行下面的onerror操作
  33. self[0].onerror = function(){
  34. /*this.style.background = 'url(pic/compressed/picList18.jpg) center no-repeat';*/
  35. countPic();
  36. }
  37.  
  38. },1000*index);
  39.  
  40. })
  41.  
  42. }
  43.  
  44. /*根据onload的执行情况来计算当前的图片加载进度.每onload一次,activePic就增加1*/
  45.  
  46. function countPic(){
  47.  
  48. activePic++;
  49.  
  50. var leftPic = totalPic - activePic;
  51. var percentPic = Math.ceil(leftPic/totalPic*100);//没有加载的图片百分比,和loadBarMask的宽度占比配合
  52.  
  53. console.log("已加载"+(100-percentPic)+"%");
  54.  
  55. loadBarMask.css("width",percentPic+"%");
  56.  
  57. if(percentPic==0){
  58. $('#loadBar').hide();
  59. }
  60. }

二、瀑布流加载

主要思路:

  1. 监听窗口滚动情况,当已经加载的图片的最后一张快要进入窗口的时候,开始加载下面的图片。

  2. 假设所有的图片地址已经存在一个json数据中,每次读取10张图片地址,加载它们之后,插入到现有的瀑布流末尾。

  3. 如此往复,直到加载完所有图片。


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

js部分

  1. var lazyPic = $('img.lazy');
  2. var loadBarMask = $('#loadBarMask');
  3. var picList = $('.picList');
  4.  
  5. var scrollTop,
  6. clientHeight,
  7. scrollHeight;
  8.  
  9. var threshold = 200; //最后一张图片距离窗口200px的时候开始加载图片
  10.  
  11. var src = [];
  12.  
  13. var activePic = 0;
  14. var totalPic = lazyPic.length;
  15.  
  16. //待加载的图片数据
  17. var dirtSrc = "pic/compressed/picList";
  18. var picData = {imgSrc:[
  19. dirtSrc + "20.jpg",
  20. dirtSrc + "21.jpg",
  21. dirtSrc + "22.jpg",
  22. dirtSrc + "23.jpg",
  23. dirtSrc + "24.jpg",
  24. dirtSrc + "25.jpg",
  25. dirtSrc + "26.jpg",
  26. dirtSrc + "27.jpg",
  27. dirtSrc + "28.jpg",
  28. dirtSrc + "29.jpg",
  29. dirtSrc + "30.jpg",
  30. dirtSrc + "31.jpg",
  31. dirtSrc + "32.jpg",
  32. dirtSrc + "33.jpg",
  33. dirtSrc + "34.jpg",
  34. dirtSrc + "35.jpg",
  35. dirtSrc + "36.jpg",
  36. dirtSrc + "37.jpg",
  37. dirtSrc + "38.jpg",
  38. dirtSrc + "39.jpg",
  39. dirtSrc + "40.jpg",
  40. dirtSrc + "41.jpg",
  41. dirtSrc + "42.jpg",
  42. dirtSrc + "43.jpg",
  43. dirtSrc + "44.jpg",
  44. dirtSrc + "45.jpg",
  45. dirtSrc + "46.jpg",
  46. dirtSrc + "47.jpg",
  47. dirtSrc + "48.jpg",
  48. dirtSrc + "49.jpg",
  49. ]};
  50.  
  51. //加载次数计数器
  52. var scrollIndex = 0;
  53.  
  54. $(function(){
  55.  
  56. /*监听窗口滚动情况*/
  57. $(window).on('scroll',function(){
  58.  
  59. scrollTop = $(window).scrollTop();//$(window).scrollTop()==document.body.scrollTop
  60. clientHeight = $(window).height();
  61. scrollHeight = picList.last().height();//picList.last()[0].clientHeight
  62.  
  63. /*目标与窗口的距离达到阈值时开始加载*/
  64. if(scrollHeight-clientHeight-scrollTop < threshold){
  65. scrollPic(10);
  66. }
  67. })
  68. })
  69.  
  70. /*根据滚动程度加载图片,每次加载perAmount张*/
  71.  
  72. function scrollPic(perAmount = 10){
  73.  
  74. var totalAmount = perAmount * (scrollIndex+1);
  75.  
  76. //考虑到最后一次加载的时候,剩余的图片数量有可能达不到限定的每次加载的数量,这时候需要更改totalAmount的值
  77. if(totalAmount>picData.imgSrc.length){
  78. totalAmount = picData.imgSrc.length;
  79. }
  80. for(scrollIndex;scrollIndex<totalAmount;scrollIndex++){
  81. var oimg = new Image();
  82. oimg.src = picData.imgSrc[scrollIndex];
  83. picList.append(oimg);
  84. }
  85.  
  86. }

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

三、运行效果与文件截图

1、运行效果

2、文件截图

双击"图片加载.html"即可运行。

四、后记·兼容性问题

拿到IE8之下运行时,发现img.onload后面的function打死都不执行,IE8智障到不能完成 img.onload = function(){}这么初级的代码么?

去查了资料之后,发现IE8虽然白痴,但还算没有智障到无药可救。

onload是可以调用的,但是要放在src的赋值之前。

简单来说,就是要先告诉浏览器图片加载完要怎么处理,再让它去加载图片。避免因为加载缓冲区的速度太快,在没有告诉它加载完要怎么办时,它已经加载完了。而其它浏览器则是从缓冲区读取到图片时就执行onload。

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

js图片加载效果(延迟加载+瀑布流加载)的更多相关文章

  1. js实现瀑布流加载图片效果

    今天学习了一个瀑布流加载效果,很多网站都有瀑布流效果,瀑布流就是很多产品显示在网页上,宽相同,高度不同,表现为多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.原理是:1. ...

  2. ASP.NET仿新浪微博下拉加载更多数据瀑布流效果

    闲来无事,琢磨着写点东西.貌似页面下拉加载数据,瀑布流的效果很火,各个网站都能见到各式各样的展示效果,原理大同小异.于是乎,决定自己写一写这个效果,希望能给比我还菜的菜鸟们一点参考价值. 在开始之前, ...

  3. WAP用户评论简单实现瀑布流加载

    wap端经常会遇到产品或者评论的加载,但是分页的体验不是很好,所以选择通过js实现瀑布流加载方式. 第一步:需要动态加载的主要内容,这里需要动态加载的是li标签的内容 <ul class=&qu ...

  4. css3多列布局瀑布流加载样式

    看了一些网站的瀑布流加载,正好看到css3的多列属性,尝试着写了一个css做布局的瀑布流. 直接上代码: <!DOCTYPE html> <html lang="en&qu ...

  5. JS图片灯箱(lightBox)效果基本原理和demo

    到年底了,项目不怎么忙,所以有空特地研究了下KISSY中源码JS灯箱效果,感觉代码比较简单,所以就按照他们的思路依赖于Jquery框架也封装了一个,特地分享给大家,以前经常看到网上很多这样的插件,感觉 ...

  6. js图片轮播效果实现代码

    首先给大家看一看js图片轮播效果,如下图 具体思路: 一.页面加载.获取整个容器.所有放数字索引的li及放图片列表的ul.定义放定时器的变量.存放当前索引的变量index 二.添加定时器,每隔2秒钟i ...

  7. Entity Framework关联查询以及数据加载(延迟加载,预加载)

    数据加载分为延迟加载和预加载 EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Lo ...

  8. 原声JS瀑布流加延迟载入

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. jQuery ajax瀑布流加载静态的列表页面

    1.加载一行数据 <script> //滚动加载事件 var Loadurl = "{$url}"; if(window.location.href !== Loadu ...

随机推荐

  1. EXC_BAD_ACCESS(code=2,address=0xcc 异常解决 及 建议不要在子线程中刷新界面

    iOS 上不建议在非主线程进行UI操作,在非主线程进行UI操作有很大几率会导致程序崩溃,或者出现预期之外的效果. 我开始不知道这一点,在子线程中进行了弹窗操作,结果程序就出问题了! 报的错误是(EXC ...

  2. Python3.6学习笔记(二)

    Python 的高级特性 切片 对于指定索引范围取值的操作,Python提供了slice方法,类似于Excel中数据透视表的切片器. >>> L = ['Michael', 'Sar ...

  3. HorizontalScrollView的使用演示样例

    MainActivity例如以下: package cc.cv; import android.os.Bundle; import android.view.LayoutInflater; impor ...

  4. Linked List Cycle leetcode II java (寻找链表环的入口)

    题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...

  5. 一行代码轻松实现拖动效果[JQuery]

    写JS实现拖动需要一大堆不便维护的代码,实属麻烦,Google了大半天,发现了一个优秀的Jquery插件EasyDrag,只需要一行代码便可轻松在主流浏览器上 实现拖动效果.   $(document ...

  6. C#的几种写文件方法

    C#写文件处理操作在很多的开发项目中都会涉及,那么具体的实现方法是什么呢?这里向大家介绍三大方法,希望对你在开发应用中有所启发. 首先C#写文件处理操作必须先导入命名空间:using System.I ...

  7. Vue路由scrollBehavior滚动行为控制锚点

    使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样. vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动. 注意: 这个功能只 ...

  8. Transform导入数据源TR1008错误

    cognos在建设初期开发者们都常常遇到的一个问题,在这里做一下小小的总结. iqd作为Transform的数据源导入数据的时候遭遇TR1008错误 注意: 从报错的内容可以看出transform不能 ...

  9. [Node.js]29. Level 6: Socket.io: Setting up Socket.io server-side & Client socket.io setup

    Below we've already created an express server, but we want to start building a real-time Q&A mod ...

  10. boost::tie()和boost::variant()解说

    #include<iostream> #include<boost/tuple/tuple.hpp> #include<boost/variant.hpp> #in ...