该插件在较长的页面中延迟加载图片。视窗外的图片会延迟加载,直到它们由于用户滚动而出现到视窗中。可以将它看做图像预加载技术的反向运用。
在包含很多大图片且较长页面中使用延迟加载,能使页面载入更快。浏览器在只加载可见区域的图片后就达到绪状态。在某些情况下,它也能帮助减少服务器端的负载。
图片延迟加载的灵感来自于Matt Mlinac的 YUI ImageLoader 技术。
这个项目由 tuupola/jquery_lazyload fork而来,并加入了如下功能:
- 修改了许多细节来提升性能;
- 加入了对IE6/7的支持;
- 可以在图片加载之前再根据需求动态修改图片的url;
- 可以基于 Zepto 使用,而不是只能基于jQuery;
- `vertical_only` 、 `no_fake_img_loader` 、`check_appear_throttle_time` 等额外的选项。
图片延迟加载插件基于jQuery或Zepto,在你HTML代码的尾部引入他们:
<script src="jQuery.js"></script> <!-- 或 <script src="zepto.js"> --> <script src="lazyload.min.js"></script>
或者用 Bower (http://bower.io/) 安装:
bower install jieyou_lazyload
你必须改写你的HTML代码。真实图像的URL必须被放入到`data-original`属性中。给所有需要延迟加载图片一个特殊的class是一个好主意。这样你就可以很容易地控制哪些图片会被插件绑定到。请注意,你的图片应该有宽度和高度属性,或者通过CSS来控制图片的宽度和高度,或者通过某些手段来确保它有正确的宽度和宽度。
<!-- 直接赋予图片宽高 --> <img class="lazy" data-original="img/example.jpg" width="640" height="480"> <!-- 或:通过css赋予图片宽高 --> <style> .lazy{width:640px;height:480px;} </style> <img class="lazy" data-original="img/example.jpg"> <!-- 或:自适应宽度的图片样式(常用于移动端) --> <style> .lazy{width:100%;height:0;padding-top:75%;background-size:100%;} /* 假设高宽比为 480:640,即75%,并使用背景图的方式将图片铺在padding-top区域内 (padding的百分比是宽度的百分比而不是高度的,即使是padding-top|padding-bottom) */ </style> <div class="lazy" data-original="img/example.jpg"><div> <!-- 请参阅examples/enabled_image_full_width.html -->
然后你在你的代码中加入:
$(".lazy").lazyload();
这会使得所有class为lazy的元素被延迟加载
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("#container").one("click", function() { $("#container").load("images.html", function(response, status, xhr) { $("img.lazy").lazyload(); }); });
请参阅 `enabled_ajax.html`
<div class="lazy" data-original="img/bmw_m1_hood.jpg" style="background-image: url('img/grey.gif'); width: 765px; height: 574px;"></div>
$("div.lazy").lazyload(); // 或加入某些效果 $("div.lazy").lazyload({ effect : "fadeIn" });
请参阅 `enabled_background.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
#container { height: 600px; overflow: scroll; }
$("img.lazy").lazyload({ effect : "fadeIn", container: $("#container") });
请参阅 `enabled_container.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
<script src="jquery.scrollstop.js" type="text/javascript"></script>
$("img.lazy").lazyload({ event: "scrollstop" });
请参阅 `enabled_gazillion.php`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
#container { width: 800px; overflow: scroll; } #inner_container { width: 4750px; }
$("img.lazy").lazyload({ container: $("#container") });
请参阅 `enabled_wide_container.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("img.lazy").lazyload({ effect : "fadeIn" });
请参阅 `enabled_fadein.html`
<img class="lazy" src="img/grey.gif" data-original="img/example.jpg" width="765" height="574">
$(function() { $("img.lazy").lazyload({ event : "sporty" }); }); $(window).bind("load", function() { var timeout = setTimeout(function() { $("img.lazy").trigger("sporty") }, 5000); });
请参阅 `enabled_timeout.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("img.lazy").lazyload();
请参阅 `enabled_wide.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("img.lazy").lazyload({ vertical_only: true });
请参阅 `enabled_vertical_only.html`
某些情况下,你需要对图片的原始url做一些处理
<img class="lazy" data-original="img/bmw_m1_hood.jpg" width="765" height="574">
$("img.lazy").lazyload({ url_rewriter_fn:function($element,originalSrcInAttr){ // this -> image element if(originalSrcInAttr == 'img/bmw_m1_hood.jpg'){ // in the example, we changed the first image's url to another return 'img/bmw_m1_hood_rewritten.jpg' } return originalSrcInAttr } }) // 回调函数中,`this`指向出现的图片元素的节点,参数第一项为当前元素的jQuery|Zepto对象,第二项为当前元素的图片的原始url
默认情况下,我们在加载图片时,会先创建一个 Image 对象(fake image)将远端的图片加载到本地,再更改真正需要此图片的元素的 src 或 background-image 属性。这样用户看上去图片不是被缓慢加载出来的,而是在立即展现,或能添加诸如 fadeIn 类的效果。
但是如果图片是从某个接口动态返回的,而不是实际的一个静态文件,上述机制在某些情况下可能导致图片被加载两次(创建的Image对象会加载一次,实际DOM树中的元素设置 src 或 background-image 时又会加载一次),此时你可以将 no_fake_img_loader 参数设置为true,这样不会有 fake image 的机制,从而规避这种问题。
请注意 与srcset属性一起使用 时,则一定会开启“不使用假图片预加载”,而无论你设置的no_fake_img_loader的值是true还是false。
<img class="lazy" data-original="img/bmw_m1_hood.jpg" width="765" height="574">
$("img.lazy").lazyload({ no_fake_img_loader:true })
请参阅 `enabled_no_fake_img_loader.html`
<img class="lazy" data-original="img/bmw_m1_hood.jpg" width="765" height="574">
require(['jquery','../lazyload'],function($){ $(".lazy").lazyload() })
请参阅 `enabled_amd.html`
更多详情请见 `enabled_srcset.html`
<img class="lazy" data-original="img/bmw_m1_hood.jpg" data-original-srcset="img/bmw_m1_hood.jpg 765w" sizes="765px" width="765" height="574">
$("img.lazy").lazyload()
请参阅 `enabled_srcset.html`
你可以将options对象当做`lazyload`方法的第一个参数来使用。
var options = { // 默认情况下,图像会在出现在屏幕上时被加载。如果你想的图像更早地加载,可以使用threshold参数。设置threshold为200,将导致图像在它离视窗边缘还有200px时开始加载。 threshold : 0, // default: 0. 另一个例子: 200 // 在页面滚动后,该插件将所有未加载的图像循环一遍。并在循环检查图像是否在视窗中。默认情况下,发现第一个位于视窗外的图片时,循环停止。这是基于以下的假设:页面上图像的顺序与它们在HTML代码中的顺序是一致的。然而对于某些布局,这可能是错误的。你可以通过设置failure_limit参数来控制循环终止的行为(failure_limit参数的数值为最多允许多少张图片被检查出位于视窗外后停止检查循环中剩余未检查的图片),当你将它设置为一个比较大的数值,显著多余总的图片数量(如9999)时,则可以认为会检测到每一张图片。 failure_limit : 0, // default: 0. 另一个例子: 10 // 指定触发什么事件时,开始加载真实的图片。你可以使用jQuery中已有的事件,如click或mouseover。你也可以使用自定义的事件如sporty或foobar。当事件是`scroll`或类似事件类型时,还需要检查图像是否已出现在视窗中。 event : 'scroll', // default: 'scroll'. 另一个例子: 'click' // 默认情况下插件在等待图片完全加载后调用show()。你可以使用想要的任何效果。下面的代码使用了fadeIn效果。你可以在demo页面中查看该效果。 effect : 'show', // default: 'show'. 另一个例子: 'fadein' // 上述效果(`effect`)函数的参数数组。举两个例子,如果`effect`参数设置为`show`且`effect_params`参数设置为[400],将会调用`$element.show(400)`,即在400ms后显示图片;如果`effect`参数设置为`fadein`且`effect_params`参数设置为[400,completeFunction],将会调用`fadein(400,completeFunction)`,即在400ms内渐入显示图片,并在渐入动画完成时调用`completeFunction`。 effect_params : null, // default: undefined. 另一个例子: [400]. // 你可以将改插件运用在某个容器内,如一个有滚动条的div。只需要传递容器的jQuery对象。我们有在纵向和横向滚动的容器中使用插件的两个demo。 container : window, // default: 'show'. 另一个例子: $('#container') // 默认情况下,图片的真实url被设置在`data-original`属性内,你可以通过修改下面这个值来改变这个属性名(如`url`,这样插件将在`data-url`属性中查找图片的真实地址)注意下面这个值是不用包含`data-`头的。 data_attribute : 'original', // default: 'original'. 另一个例子: 'url' // 当你将图片懒加载技术与`srcset`一起使用时,你不能将`srcset`的值直接写在`srcset`内,否则会导致图片立即加载。默认情况下,你应该写在属性`data-original-srcset`内,这样lazyload插件会帮你在合适的时候将它的赋值到`srcset`上。你可以通过修改下面这个值来改变这个属性名。注意下面这个值是不用包含`data-`头的。 data_srcset_attribute : 'original-srcset', // default: 'original-srcset'. 另一个例子: 'o-srcset' // 当图片在视窗中出现时回调。`this`指向出现的图片元素的节点,参数第一项为当前元素的jQuery|Zepto对象,第二项为尚未出现的图片的数量,第三项为配置参数对象。 appear : function(){}, // default: `the emptyFunc`. 另一个例子: function($elements, elements_left, options){} // 当图片加载完毕时回调。`this`指向出现的图片元素的节点,参数第一项为当前元素的jQuery|Zepto对象,第二项为尚未出现的图片的数量,第三项为配置参数对象。 load : function(){}, // default: `the emptyFunc`. 另一个例子: function($elements, elements_left, options){} // 在大多数情况下,页面只能纵向滚动。此时,只需要检查图片的竖直位置是否出现在视图中即可。如果这样做能提高性能。你可以在只能纵向滚动的页面中将`vertical_only`参数设置为true vertical_only : false, // default: false. 另一个例子: true // 默认情况下,lazyload会在`window`的`scroll`、`resize`事件被触发时,检查图片是否已经出现在视窗中,但用户一次缩放屏幕通常可能连续触发多次resize事件;除了iOS以外的设备,用户一次滚屏也可能触发多次scroll事件,这造成了性能上的浪费。你可以通过这个参数设置两次检查之间最少的间隔时间,用来提高性能。当设置为0时,则每次触发`scroll`、`resize`事件时都会检测 check_appear_throttle_time : 300, // default: 300. 另一个例子: 0 // 重写图片的原始url。回调函数中,`this`指向出现的图片元素的节点,参数第一项为当前元素的jQuery|Zepto对象,第二项为当前元素的图片的原始url url_rewriter_fn : function(){}, // default: `the emptyFunc`. 另一个例子: function($element,originalSrcInAttr){} // 不使用假图片预加载(详见上面“高级”中的“不使用假图片预加载”) no_fake_img_loader : false, // default: false. 另一个例子: true // 如果一个img元素没有指定src属性,我们使用这个placeholder,在真正的图片被加载之前,此img会呈现这个占位图。 placeholder_data_img : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC', // IE6/7 的 placeholder。这是我当时在百度时的cdn地址,建议改为你服务器上的任一张灰色或白色的1*1的小图 placeholder_real_img : 'http://webmap3.map.bdimg.com/yyfm/lazyload/0.0.1/img/placeholder.png' } $("img.lazy").lazyload(options);
由于display:none时,jQuery/Zepto中的`$(selector).offset().top/left`属性始终为0( 链接 ),因此该属性为false并且图片一开始display:none时,由于无法得到该标签距离文档顶部的实际像素数,图片在一开始就会被加载上来,违背了lazyload的初衷。因此该版本中删掉了该属性。lazyload不会去管display:none的图片,可能会出现当将display:none改变为其它值,图片仍然没有被加载的情况,但是只要滑动滚轮触发scroll或event中设定的事件,图片还是可以被加载出来的,examples中的remove_invisible.html展示了这一场景
所有代码遵循 MIT License. 所有图片license是 Creative Commons Attribution 3.0 Unported License 。也就是说你可以自由地做任何你想做的事情。只是不能在代码中移除我的名字。
Lazy Load delays loading of images in long web pages. Images outside of viewport wont be loaded before user scrolls to them. This is opposite of image preloading.
Using Lazy Load on long web pages containing many large images makes the page load faster. Browser will be in ready state after loading visible images. In some cases it can also help to reduce server load.
Lazy Load is inspired by YUI ImageLoader Utility by Matt Mlinac.
This project is forked from tuupola/jquery_lazyload and add features below:
- Modified many details to improve performance;
- IE6/7 supported;
- Can dynamically modify the image’s url on demand before image loaded;
- Available with Zepto ;
- `vertical_only` \ `minimum_interval` \ `use_minimum_interval_in_ios` \ `no_fake_img_loader` options.
Lazy Load depends on jQuery or Zepto. Include them in end of your HTML code:
<script src="jquery.js"></script> <!-- or <script src="zepto.js"> --> <script src="lazyload.min.js"></script>
You can use our cdn server:
<script src="http://webmap2.map.bdimg.com/yyfm/jQuery_1.x/1.10.2/js/jQuery_1.x.min.js"></script> <!-- or <script src="http://webmap2.map.bdimg.com/yyfm/zepto_default/1.1.2/js/zepto_default.min.js"></script> --> <script src="http://webmap3.map.bdimg.com/yyfm/lazyload/1.0.0/js/lazyload.min.js"></script>
You must alter your HTML code. URL of the real image must be put into data-original attribute. It is good idea to give Lazy Loaded image a specific class. This way you can easily control which images plugin is binded to. Note that you should have width and height attributes in your image tag, or gives the width and height via CSS.
<!-- gives image's width and height directly --> <img class="lazy" data-original="img/example.jpg" width="640" height="480"> <!-- or : gives the width and height via CSS --> <style> .lazy{width:640px;height:480px;} </style> <img class="lazy" data-original="img/example.jpg"> <!-- or : image with self-adaptive width (commonly used in the mobile) --> <style> .lazy{width:100%;height:0;padding-top:75%;background-size:100%;} /* Assuming that the aspect ratio of 480:640, i.e. 75%, and use the image as a background image plated in `padding-top` area (The percentage is the percentage of the width of the padding instead of the height even is `padding-top` or `padding-bottom`) */ </style> <div class="lazy" data-original="img/example.jpg"><div> <!-- see : examples/enabled_image_full_width.html -->
then in your code do:
$(".lazy").lazyload();
This causes all elements of class lazy to be lazy loaded.
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("#container").one("click", function() { $("#container").load("images.html", function(response, status, xhr) { $("img.lazy").lazyload(); }); });
See `enabled_ajax.html`
<div class="lazy" data-original="img/bmw_m1_hood.jpg" style="background-image: url('img/grey.gif'); width: 765px; height: 574px;"></div>
$("div.lazy").lazyload(); // Or add some effect $("div.lazy").lazyload({ effect : "fadeIn" });
See `enabled_background.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
#container { height: 600px; overflow: scroll; }
$("img.lazy").lazyload({ effect : "fadeIn", container: $("#container") });
See `enabled_container.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
<script src="jquery.scrollstop.js" type="text/javascript"></script>
$("img.lazy").lazyload({ event: "scrollstop" });
See `enabled_gazillion.php`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
#container { width: 800px; overflow: scroll; } #inner_container { width: 4750px; }
$("img.lazy").lazyload({ container: $("#container") });
See `enabled_wide_container.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("img.lazy").lazyload({ effect : "fadeIn" });
See `enabled_fadein.html`
<img class="lazy" src="img/grey.gif" data-original="img/example.jpg" width="765" height="574">
$(function() { $("img.lazy").lazyload({ event : "sporty" }); }); $(window).bind("load", function() { var timeout = setTimeout(function() { $("img.lazy").trigger("sporty") }, 5000); });
See `enabled_timeout.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("img.lazy").lazyload();
See `enabled_wide.html`
<img class="lazy" data-original="img/example.jpg" width="765" height="574">
$("img.lazy").lazyload({ vertical_only: true });
See `enabled_vertical_only.html`
Sometimes, you need do something with the original url
<img class="lazy" data-original="img/bmw_m1_hood.jpg" width="765" height="574">
$("img.lazy").lazyload({ url_rewriter_fn:function($element,originalSrcInAttr){ // this -> image element if(originalSrcInAttr == 'img/bmw_m1_hood.jpg'){ // in the example, we changed the first image's url to another return 'img/bmw_m1_hood_rewritten.jpg' } return originalSrcInAttr } }) // the arguments for callback function // `this` : currect image element node // 1st: currect element's jQuery|Zepto objcet // 2nd: currect element's original image src
see `enabled_url_rewriter_fn.html`
By default, when loading a image, we firtst create a Image object ( fake image ) which used to download the remote image to local, and then modify the `src` or `background-image` attribute to the real element which need the image. By doing this, the users feel like the images showing immediately or can use some dynamic effect such as `fadeIn` , rather than a slowly downloading.
But if the image is returned by a dynamic interferce instead of a static file, the mechanism above may cause the image being loaded twice ( fake image object once, when setting the attribute `src` or `background-image` of the real element once more ), when this occurs, you can set the `no_fake_img_loader` parameter `true`, without the `fake image` mechanism to avoid this problem.
Note that if use the `srcset` attribute, will enabled no_fake_img_loader, regardless of the value of this option is true or false.
<img class="lazy" data-original="img/bmw_m1_hood.jpg" width="765" height="574">
$("img.lazy").lazyload({ no_fake_img_loader:true })
see `enabled_no_fake_img_loader.html`
<img class="lazy" data-original="img/bmw_m1_hood.jpg" width="765" height="574">
require(['jquery','../lazyload'],function($){ $(".lazy").lazyload() })
see `enabled_amd.html`
more details on `enabled_srcset.html`
<img class="lazy" data-original="img/bmw_m1_hood.jpg" data-original-srcset="img/bmw_m1_hood.jpg 765w" sizes="765px" width="765" height="574">
$("img.lazy").lazyload()
see `enabled_srcset.html`
You can use the options object as the first argument in the `lazyload` method.
var options = { // By default images are loaded when they appear on the screen. If you want images to load earlier use threshold parameter. Setting threshold to 200 causes image to load 200 pixels before it appears on viewport. threshold : 0, // default: 0. Another example: 200 // After scrolling page plugin loops though unloaded images. Loop checks if image has become visible. By default loop is stopped when first image outside viewport is found. This is based on following assumption. Order of images on page is same as order of images in HTML code. With some layouts assumption this might be wrong. You can control loading behaviour with failure_limit setting, if you set it to a relatively large value, significantly more than the total number of images (such as 9999), it is considered that checks each images. failure_limit : 0, // default: 0. Another example: 10 // Specified an event, when it triggers, start loading the real images. You can use jQuery event such as click or mouseover. You can also use custom events such as sporty or foobar. if the event is `scroll` or a similar type, it also need to check if the image has appeared in the viewport. Default is to wait until user scrolls down and image appears on the viewport. event : 'scroll', // default: 'scroll'. Another example: 'click' // By default plugin waits for image to fully load and calls show(). You can use any effect you want. Following code uses fadeIn effect. Check how it works at effect demo page. effect : 'show', // default: 'show'. Another example: 'fadein' // the arguments array of `effect` function. For two examples, if `effect` is set to `show` and `effect_params` is set to [400], it will call `$element.show(400)` to show the image after 400ms; if `effect` is set to `fadein` and `effect_params` is set to [400,completeFunction], it will call `$element.fadein(400,completeFunction)` to fadeIn the image in 400ms and call the `completeFunction` when the animation is complete. effect_params : null, // default: undefined. Another example: [400]. // You can also use plugin for images inside scrolling container, such as div with scrollbar. Just pass the container as jQuery object. There is a demo for horizontal and vertical container. container : window, // default: 'show'. Another example: $('#container') // By default images's original url set in `data-original` attribute, you can change it to Another attribute (such as `url`,so it will find the original url in `data-url` attribute). You can modify the following option's values to change the attribute name. Note that this value is not include `data-` prefix. data_attribute : 'original', // default: 'original'. Another example: 'url' // when use with `srcset` attribute ,you can not directly write the value of` srcset` in `srcset` attribute,otherwise it will cause the image immediately loaded。By default, you can write in the attribute `data-original-srcset` , so the lazyload plugin will help you at the right time it is assigned to the` srcset` attribute . You can modify the following option's values to change the attribute name. Note that this value is not include `data-` prefix. data_srcset_attribute : 'original-srcset', // default: 'original-srcset'. Another example: 'o-srcset' // Call when one image is appear to the viewport. The arguments for callback function: `this` : currect image element node, 1st: currect element's jQuery|Zepto objcet, 2nd: count of elements not appear yet, 3rd: the options. appear : function(){}, // default: `the emptyFunc`. Another example: function(elements_left, options){} // Call when one image is load. The arguments for callback function: `this` : currect image element node, 1st: currect element's jQuery|Zepto objcet, 2nd: count of elements not appear yet, 3rd: the options. load : function(){}, // default: `the emptyFunc`. Another example: function(elements_left, options){} // In most situations, page can only scroll vertically.At this time, only check images's vertical position will improve performance.You can only set vertical_only to true when page can only scroll vertically. vertical_only : false, // default: false. Another example: true // By default, lazyload will check whether the image has appeared in the viewport when `window`'s `scroll` or `resize` event is triggered, but once a user continuous zoom screens may usually triggered several times `resize` event; in addition to the iOS device, a user may also trigger several times `scroll` event once a scroll screen, which resulted in the waste of a performance. set the minimum interval between checks. When set to `0`, it will check in every scroll\resize event. check_appear_throttle_time : 300, // default: 300. Another example: 0 // rewrite image's original url. the arguments for callback function: `this` : currect image element node, 1st: currect element's jQuery|Zepto objcet, 2nd: currect element's original image src url_rewriter_fn : function(){}, // default: `the emptyFunc`. Another example: function($element,originalSrcInAttr){} // Without fake image preload mechanism(See details above) no_fake_img_loader : false, // default: false. Another example: true // If element is an img and no src attribute given, use placeholder. Before the real image is loaded, this will show this img placeholder. placeholder_data_img : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC', // Placeholder for IE6/7. This is Baidu's cdn addresses, I recommend that you change the url to your server ,on either a gray or white small 1 * 1 png. placeholder_real_img : 'http://ditu.baidu.cn/yyfm/lazyload/0.0.1/img/placeholder.png' } $("img.lazy").lazyload(options);
`$(selector).offset().top/left` are always zero( link ) when `display:none` is set. As we can’t get real offset of the element, the picture is always loaded when we set both `display:none` and ‘skip_invisible = false’. It go against the intention of lazyload, so we decide to remove this attribute from options. lazyload will ignore pictures with display attribute set to none. Lazyload will not be triggered when display attribute is changed(i.e. remove_invisible.html). It may cause some trouble sometimes but scrolling your mouse will definately help!
All code licensed under the MIT License. All images licensed under Creative Commons Attribution 3.0 Unported License. In other words you are basically free to do whatever you want. Just don’t remove my name from the source.