js图片加载效果(延迟加载+瀑布流加载)
概述
详细
主要做了两种图片加载的效果
一种是遇到页面图片比较多的时候,带读条效果的加载提示(为了验证正确加载,设置了1秒钟的加载间隔时间)
另外一种是根据滑块的位置进行图片的预加载,在用户不察觉的情况下,实现瀑布流的加载效果
一、延迟加载
1、需要准备什么环境
2、需要开通什么服务,如果有的话
3、本例子实现什么功能
二、程序实现
主要思路:
HTML的img标签中,将正确的地址存在data-src属性中,给所有图片设置一个转圈圈的loading图片作为background
js中,依次读取每一个img,将data-src中的地址替换到src中,去掉background
每成功加载一张图片,进度条的百分比进行相应的变化。
如果加载不成功,就提示图片加载错误。
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,编译时会自动加上各种兼容前缀)
- .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里面需要注意的地方有两个:
一个是把图片加载错误时显示的灰底文字放在了img的after伪类中,当图片加载失败,又去掉了background的gif图片之后,就会显示这个部分的内容及样式。
一个是进度条的样式。写得很简单,主要是一层带渐变的绿色和一层白色叠在一起。绿色表示已加载,白色表示未加载。显示的时候,直接控制白色那层的宽度即可。
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();
- }
- }
二、瀑布流加载
主要思路:
监听窗口滚动情况,当已经加载的图片的最后一张快要进入窗口的时候,开始加载下面的图片。
假设所有的图片地址已经存在一个json数据中,每次读取10张图片地址,加载它们之后,插入到现有的瀑布流末尾。
如此往复,直到加载完所有图片。
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都写上了,以后可以直接用。将数值关系搞定之后,只要满足条件就触发加载即可。
三、运行效果与文件截图
1、运行效果
2、文件截图
双击"图片加载.html"即可运行。
四、后记·兼容性问题
拿到IE8之下运行时,发现img.onload后面的function打死都不执行,IE8智障到不能完成 img.onload = function(){}这么初级的代码么?
去查了资料之后,发现IE8虽然白痴,但还算没有智障到无药可救。
onload是可以调用的,但是要放在src的赋值之前。
简单来说,就是要先告诉浏览器图片加载完要怎么处理,再让它去加载图片。避免因为加载缓冲区的速度太快,在没有告诉它加载完要怎么办时,它已经加载完了。而其它浏览器则是从缓冲区读取到图片时就执行onload。
注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
js图片加载效果(延迟加载+瀑布流加载)的更多相关文章
- js实现瀑布流加载图片效果
今天学习了一个瀑布流加载效果,很多网站都有瀑布流效果,瀑布流就是很多产品显示在网页上,宽相同,高度不同,表现为多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.原理是:1. ...
- ASP.NET仿新浪微博下拉加载更多数据瀑布流效果
闲来无事,琢磨着写点东西.貌似页面下拉加载数据,瀑布流的效果很火,各个网站都能见到各式各样的展示效果,原理大同小异.于是乎,决定自己写一写这个效果,希望能给比我还菜的菜鸟们一点参考价值. 在开始之前, ...
- WAP用户评论简单实现瀑布流加载
wap端经常会遇到产品或者评论的加载,但是分页的体验不是很好,所以选择通过js实现瀑布流加载方式. 第一步:需要动态加载的主要内容,这里需要动态加载的是li标签的内容 <ul class=&qu ...
- css3多列布局瀑布流加载样式
看了一些网站的瀑布流加载,正好看到css3的多列属性,尝试着写了一个css做布局的瀑布流. 直接上代码: <!DOCTYPE html> <html lang="en&qu ...
- JS图片灯箱(lightBox)效果基本原理和demo
到年底了,项目不怎么忙,所以有空特地研究了下KISSY中源码JS灯箱效果,感觉代码比较简单,所以就按照他们的思路依赖于Jquery框架也封装了一个,特地分享给大家,以前经常看到网上很多这样的插件,感觉 ...
- js图片轮播效果实现代码
首先给大家看一看js图片轮播效果,如下图 具体思路: 一.页面加载.获取整个容器.所有放数字索引的li及放图片列表的ul.定义放定时器的变量.存放当前索引的变量index 二.添加定时器,每隔2秒钟i ...
- Entity Framework关联查询以及数据加载(延迟加载,预加载)
数据加载分为延迟加载和预加载 EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Lo ...
- 原声JS瀑布流加延迟载入
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- jQuery ajax瀑布流加载静态的列表页面
1.加载一行数据 <script> //滚动加载事件 var Loadurl = "{$url}"; if(window.location.href !== Loadu ...
随机推荐
- EXC_BAD_ACCESS(code=2,address=0xcc 异常解决 及 建议不要在子线程中刷新界面
iOS 上不建议在非主线程进行UI操作,在非主线程进行UI操作有很大几率会导致程序崩溃,或者出现预期之外的效果. 我开始不知道这一点,在子线程中进行了弹窗操作,结果程序就出问题了! 报的错误是(EXC ...
- Python3.6学习笔记(二)
Python 的高级特性 切片 对于指定索引范围取值的操作,Python提供了slice方法,类似于Excel中数据透视表的切片器. >>> L = ['Michael', 'Sar ...
- HorizontalScrollView的使用演示样例
MainActivity例如以下: package cc.cv; import android.os.Bundle; import android.view.LayoutInflater; impor ...
- Linked List Cycle leetcode II java (寻找链表环的入口)
题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...
- 一行代码轻松实现拖动效果[JQuery]
写JS实现拖动需要一大堆不便维护的代码,实属麻烦,Google了大半天,发现了一个优秀的Jquery插件EasyDrag,只需要一行代码便可轻松在主流浏览器上 实现拖动效果. $(document ...
- C#的几种写文件方法
C#写文件处理操作在很多的开发项目中都会涉及,那么具体的实现方法是什么呢?这里向大家介绍三大方法,希望对你在开发应用中有所启发. 首先C#写文件处理操作必须先导入命名空间:using System.I ...
- Vue路由scrollBehavior滚动行为控制锚点
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样. vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动. 注意: 这个功能只 ...
- Transform导入数据源TR1008错误
cognos在建设初期开发者们都常常遇到的一个问题,在这里做一下小小的总结. iqd作为Transform的数据源导入数据的时候遭遇TR1008错误 注意: 从报错的内容可以看出transform不能 ...
- [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 ...
- boost::tie()和boost::variant()解说
#include<iostream> #include<boost/tuple/tuple.hpp> #include<boost/variant.hpp> #in ...