图片惰性加载

图片惰性加载

惰性加载,延迟加载,顾名思义,就是在图片未到达可视区域时,不加载图片,我们常常在很多的优秀网站上看到类似的例子,例如迅雷、土豆、优酷等,由于一个网页的图片非常多,一次性加载增加服务器压力,而且用户未必会拉到底部,浪费用户流量,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