什么是图片惰性加载呢?
顾名思义,惰性指的是我们只将用户视野范围内(浏览器窗口的可视区域)的图片加载,而用户视野范围外的图片先不加载,当用户看到这些图片时再做加载。
这样做的好处在于哪里呢?
1、用户访问速度上升了,浏览器的加载进度条很快就加载完毕。
2、节省用户流量。
那么如何实现呢?
我们需要解决两个问题:
① 如何知道用户是否能看见这张图片?
② 如何让看不到的图片不加载,而在需要的时候再去加载?
先解决第一个问题:如何知道用户是否能看见这张图片?
首先需要获取三个值,这些都可以通过javascript获取。
①浏览器窗口的高度 windowHeight
②页面滚动的距离 windowPageY
③图片距离页面顶部的距离 imgTop
1 if(imgTop >= windowPageY && imgTop <= (windowPageY+windowHeight)){2 //图片可见
3 }
关于上面的条件判断,相信你仔细思考就能看明白。
解决第二个问题:如何让看不到的图片不加载,而在需要的时候再去加载?
所有图片元素的src值先设置为一个很小的图片或者一张“加载中”的图片,而它的真实属性放置在一个自定义属性中如:
1 <img dataimg="真实大图.png" src="小图.png">
这样浏览器只会去加载小图,而不会去加载大图,而当你所有图片都用同一张小图的时候,这张小图只需要加载一次,所以速度非常快。
当这张图片需要加载了,那么我们只需要将原先放置在自定义属性中的图片地址放置到img标签额src属性中就可以了,接下来浏览器就会去请求并加载这张图片:
1 <img dataimg="真实大图.png" src="真实大图.png">
ok,基本原理就是这样,代码细节就不赘述了,直接贴代码。
lazyload.js
001 (function(){002 /**
003 * 功能:图片惰性加载。在需要图片惰性加载的页面底部载入。再将图片加上class=“lazy”。并将图片的真实地址放置在图片的自定义属性dataimg中。
004 * @author haunghm
005 * @version 1.0.0
006 * @dependencies jquery 或者 zepto
007 */
008 var lazyLoad = {009 010 init: function() {011 var that = this;012 that.onerrorImgUrl = "./images/grey.png";//图片加载失败用什么图片替换013 that.srcStore = "dataimg"; //图片真实地址存放的自定义属性014 that.class = "lazy"; //惰性加载的图片需要添加的class015 that.sensitivity = 50; //该值越小,惰性越强(加载越少)016 017 minScroll = 5,018 slowScrollTime = 200,019 ios = navigator.appVersion.match(/(iPhone\sOS)\s([\d_]+)/),020 isIos = ios && !0 || !1,021 isoVersion = isIos && ios[2].split("_");022 023 isoVersion = isoVersion && parseFloat(isoVersion.length > 1 ? isoVersion.splice(0, 2).join(".") : isoVersion[0], 10),024 isIos = that.isPhone = isIos && isoVersion < 6;025 026 if (isIos) {027 028 var startSyAndTime,029 setTimeOut;
030 $(window).on("touchstart",function() {031 startSyAndTime = {032 sy: window.scrollY,033 time: Date.now()034 },035 setTimeOut && clearTimeout(setTimeOut)036 }).on("touchend",function(e) {037 if (e && e.changedTouches) {038 var subtractionY = Math.abs(window.scrollY − startSyAndTime.sy);039 if (subtractionY > minScroll) {040 var subtractionTime = Date.now() − startSyAndTime.time;041 setTimeOut = setTimeout(function() {042 that.changeimg(),043 startSyAndTime = {},044 clearTimeout(setTimeOut),045 setTimeOut = null046 },047 subtractionTime > slowScrollTime ? 0: 200)048 }
049 } else {050 that.changeimg();051 }
052 }).on("touchcancel", function() {053 setTimeOut && clearTimeout(setTimeOut),054 startSyAndTime = {}055 })056 } else {057 $(window).on("scroll", function() {058 that.changeimg();059 });060 }
061 setTimeout(function() {062 that.trigger();063 },90);064 065 },066 trigger: function() {067 var that = this;068 eventType = that.isPhone && "touchend" || "scroll";069 that.imglist = $('img.'+that.class+'');070 $(window).trigger(eventType);071 },072 changeimg: function() {073 function loadYesOrno(img) {074 var windowPageYOffset = window.pageYOffset,075 windowPageYOffsetAddHeight = windowPageYOffset + window.innerHeight,076 imgOffsetTop = img.offset().top;077 return imgOffsetTop >= windowPageYOffset && imgOffsetTop − that.sensitivity <= windowPageYOffsetAddHeight;078 }
079 function loadImg(img, index) {080 081 var imgUrl = img.attr(that.srcStore);082 img.attr("src", imgUrl);083 img[0].onload || (img[0].onload = function() {084 $(this).removeClass(that.class).removeAttr(that.srcStore),085 that.imglist[index] = null,086 this.onerror = this.onload = null087 },088 img[0].onerror = function() {089 this.src = that.onerrorImgUrl,090 $(this).removeClass(that.class).removeAttr(that.srcStore),091 that.imglist[index] = null,092 this.onerror = this.onload = null093 })094 }
095 var that = this;096 that.imglist.each(function(index, val) {097 if (!val) return;098 var img = $(val);099 if (!loadYesOrno(img)) return;100 if (!img.attr(that.srcStore)) return;101 loadImg(img, index);102 })103 104 }
105 };106 lazyLoad.init();107 108 }());
如何使用这个脚本呢?
01 <!DOCTYPE html>
02 <html>
03 <head>
04 <title>图片惰性演示例子</title>05 </head>
06 <body>
07 <img class="lazy" dataimg="images/change01.jpg" src="./grey.png">
08 <img class="lazy" dataimg="images/change02.jpg" src="./grey.png">
09 <img class="lazy" dataimg="images/change03.jpg" src="./grey.png">
10 <img class="lazy" dataimg="images/change04.jpg" src="./grey.png">
11 <img class="lazy" dataimg="images/change05.jpg" src="./grey.png">
12 <img class="lazy" dataimg="images/change06.jpg" src="./grey.png">
13 </body>
14 15 <script src="http://libs.baidu.com/zepto/1.0rc/zepto.min.js"></script>
16 <script src="./lazyload.js"></script>
17 18 </html>
并按照一下规则来书写你的img标签
1 <img class="lazy" dataimg="真实大图.png" src="小图.png">
好了,高潮和结局终于同时来了。我始终认为demo也需要有赏心悦目的感觉。