
惰性加载,延迟加载,顾名思义,就是在图片未到达可视区域时,不加载图片,我们常常在很多的优秀网站上看到类似的例子,例如迅雷、土豆、优酷等,由于一个网页的图片非常多,一次性加载增加服务器压力,而且用户未必会拉到底部,浪费用户流量,Lazy Load采用按需加载,更快的加载速度从而达到优化网页的目的。
这样做的好处在于哪里呢?
1、用户访问速度上升了,浏览器的加载进度条很快就加载完毕。
2、节省用户流量。
那么如何实现呢?
那么如何实现呢?
我们需要解决两个问题:
① 如何知道用户是否能看见这张图片?
②如何让看不到的图片不加载,而在需要的时候再去加载?
先解决第一个问题:如何知道用户是否能看见这张图片?
首先需要获取三个值,这些都可以通过javascript获取。
①浏览器窗口的高度windowHeight
②页面滚动的距离 windowPageY
③图片距离页面顶部的距离imgTop
Javascript|copycode|?
1if(imgTop >= windowPageY && imgTop <= (windowPageY+windowHeight)){
2 //图片可见
3}
关于上面的条件判断,相信你仔细思考就能看明白。
解决第二个问题:如何让看不到的图片不加载,而在需要的时候再去加载?
所有图片元素的src值先设置为一个很小的图片或者一张“加载中”的图片,而它的真实属性放置在一个自定义属性中如:
HTML|copycode|?
1
这样浏览器只会去加载小图,而不会去加载大图,而当你所有图片都用同一张小图的时候,这张小图只需要加载一次,所以速度非常快。
当这张图片需要加载了,那么我们只需要将原先放置在自定义属性中的图片地址放置到img标签额src属性中就可以了,接下来浏览器就会去请求并加载这张图片:
HTML|copycode|?
1
ok,基本原理就是这样,代码细节就不赘述了,直接贴代码。
lazyload.js
Javascript|copycode|?
001(function(){
002/**
003* 功能:图片惰性加载。在需要图片惰性加载的页面底部载入。再将图片加上class=“lazy”。并将图片的真实地址放置在图片的自定义属性dataimg中。
004* @author haunghm
005* @version 1.0.0
006* @dependencies jquery 或者 zepto
007*/
008var lazyLoad = {
009
010 init: function() {
011 var that = this;
012 that.onerrorImgUrl = "./images/grey.png";//图片加载失败用什么图片替换
013 that.srcStore = "dataimg"; //图片真实地址存放的自定义属性
014 that.class = "lazy"; //惰性加载的图片需要添加的class
015 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.split("_");
022
023 isoVersion = isoVersion && parseFloat(isoVersion.length > 1 ? isoVersion.splice(0, 2).join(".") : isoVersion, 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 = null
046 },
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.onload || (img.onload = function() {
084 $(this).removeClass(that.class).removeAttr(that.srcStore),
085 that.imglist[index] = null,
086 this.onerror = this.onload = null
087 },
088 img.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 = null
093 })
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};
106lazyLoad.init();
107
108}());
如何使用这个脚本呢?
HTML|copycode|?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
就像上面的代码一样,很简单。只要在页面底部载入jquery或者zepto(如果你不想依赖这两个库,也很简单,可以改造一下代码,毕竟在移动端不需要处理很多兼容性问题)。然后载入lazyload.js这个脚本。
并按照一下规则来书写你的img标签
HTML|copycode|?
1
