修改jquery.lazyload.js实现页面延迟载入
jquery.lazyload.js并未真正的实现页面延迟载入,它的实现原理是页面载入完毕后将html中所有img标签的src属性都替换为空,把src的初始值存储到一个自定义的属性中,当页面滚动到img标签位置时再将图片载入进来。虽然实现了延迟载入的视觉效果,但是通过httpwatch等工具就可以看到,页面载入完毕后又发布很多空请求,而空请求就是由这些被替换过的img标签产生的,空请求也会一定程度上增加页面的打开时间,所以jquery.lazyload.js并未真生的实现页面延迟载入。
我对jquery.lazyload.js做了一些修改,实现了页面的延迟载入,不仅仅是图片,html代码同样可以延迟载入,大大减少了页面发出的请求数,提高了页面的打开速度。
修改后的jquery.lazyload.js代码如下:
jquery.lazyload.js
1 /*
2 * Lazy Load - jQuery plugin for lazy loading images
3 *
4 * Copyright (c) 2007-2009 Mika Tuupola
5 *
6 * Licensed under the MIT license:
7 * http://www.opensource.org/licenses/mit-license.php
8 *
9 * Project home:
10 * http://www.appelsiini.net/projects/lazyload
11 *
12 * Version: 1.5.0
13 *
14 * Modify by @cnbaiying
15 * Modify time: 2010-12-16
16 */
17 (function($) {
18
19 $.fn.lazyload = function(options) {
20 var settings = {
21 threshold : 0, //阀值
22 failurelimit : 0,
23 event : "scroll",
24 effect : "show",
25 container : window
26 };
27
28 if(options) {
29
30 $.extend(settings, options);
31 }
32
33 /* Fire one scroll event per scroll. Not one scroll event per image. */
34 var elements = this;
35
36 if ("scroll" == settings.event) {
37 $(settings.container).bind("scroll", function(event) {
38 var counter = 0;
39 elements.each(function() {
40 if ($.abovethetop($(this).parent(), settings) || $.leftofbegin($(this).parent(), settings)) {
41 /* Nothing. */
42 } else if (!$.belowthefold($(this).parent(), settings) && !$.rightoffold($(this).parent(), settings)) {
43 $(this).trigger("appear");
44 } else {
45 if (counter++ > settings.failurelimit) {
46 return false;
47 }
48 }
49 });
50 /* Remove image from array so it is not looped next time. */
51 var temp = $.grep(elements, function(element) {
52 return !element.loaded;
53 });
54 elements = $(temp);
55 });
56 }
57
58 this.each(function() {
59 var self = this;
60 /* When appear is triggered load original image. */
61 $(self).one("appear", function() {
62 if (!this.loaded) {
63 //alert($(self).parent().html($(self).html()));
64 var tmp_str = $(self).html();
65 tmp_str = tmp_str.replace("<", "<");
66 tmp_str = tmp_str.replace(">", ">");
67 $(self).parent().append(tmp_str);
68 self.loaded = true;
69 }
70 });
71
72 /* When wanted event is triggered load original image */
73 /* by triggering appear. */
74 if ("scroll" != settings.event) {
75 $(self).bind(settings.event, function(event) {
76 if (!self.loaded) {
77 $(self).trigger("appear");
78 }
79 });
80 }
81 });
82
83 /* Force initial check if images should appear. */
84 $(settings.container).trigger(settings.event);
85
86 return this;
87
88 };
89
90 /* Convenience methods in jQuery namespace. */
91 /* Use as $.belowthefold(element, {threshold : 100, container : window}) */
92
93 $.belowthefold = function(element, settings) {
94 if (settings.container === undefined || settings.container === window) {
95 var fold = $(window).height() + $(window).scrollTop();
96 } else {
97 var fold = $(settings.container).offset().top + $(settings.container).height();
98 }
99 return fold <= $(element).offset().top - settings.threshold;
100 };
101
102 $.rightoffold = function(element, settings) {
103 if (settings.container === undefined || settings.container === window) {
104 var fold = $(window).width() + $(window).scrollLeft();
105 } else {
106 var fold = $(settings.container).offset().left + $(settings.container).width();
107 }
108 return fold <= $(element).offset().left - settings.threshold;
109 };
110
111 $.abovethetop = function(element, settings) {
112 if (settings.container === undefined || settings.container === window) {
113 var fold = $(window).scrollTop();
114 } else {
115 var fold = $(settings.container).offset().top;
116 }
117 return fold >= $(element).offset().top + settings.threshold + $(element).height();
118 };
119
120 $.leftofbegin = function(element, settings) {
121 if (settings.container === undefined || settings.container === window) {
122 var fold = $(window).scrollLeft();
123 } else {
124 var fold = $(settings.container).offset().left;
125 }
126 return fold >= $(element).offset().left + settings.threshold + $(element).width();
127 };
128 /* Custom selectors for your convenience. */
129 /* Use as $("img:below-the-fold").something() */
130
131 $.extend($.expr[':'], {
132 "below-the-fold" : "$.belowthefold(a, {threshold : 0, container: window})",
133 "above-the-fold" : "!$.belowthefold(a, {threshold : 0, container: window})",
134 "right-of-fold" : "$.rightoffold(a, {threshold : 0, container: window})",
135 "left-of-fold" : "!$.rightoffold(a, {threshold : 0, container: window})"
136 });
137
138 })(jQuery);
下面是测试页面的html代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="keywords" content="汽车图片,汽车图片壁纸, 汽车图片桌面, 汽车图片库,汽车图片大全" />
<meta name="description" content="汽车图片,网上车市汽车图片大全频道为网友提供各种汽车图片及美女图片下载,各种车型汽车图片桌面,汽车图片壁纸,车展美女图片,美女车模图片等。精彩图片,尽在网上车市。" />
<title>【汽车图片|汽车美女图片-汽车图片大全】-网上车市</title>
<style>
.switch_textarea {display:none;}
.div_style {width:600px; height:400px; }
</style>
<script type="text/javascript" src="http://js.cheshi-img.com/jquery/jquery.1.4.4.js"></script>
<script type="text/javascript" src="lazyload.jquery.js"></script>
<script>
$().ready(function(){
$(".switch_textarea").lazyload();
});
</script>
</head>
<body>
<H2>第1张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd2385fd03.jpg" /></textarea></div>
<H2>第2张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd2366adec.jpg" /></textarea></div>
<H2>第3张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd233b8da4.jpg" /></textarea></div>
<H2>第4张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd231a0fd8.jpg" /></textarea></div>
<H2>第5张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd22e68f56.jpg" /></textarea></div>
<H2>第6张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd22c55a5d.jpg" /></textarea></div>
<H2>第7张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd2278872b.jpg" /></textarea></div>
<H2>第8张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd224a0f6e.jpg" /></textarea></div>
<H2>第9张图</H2>
<div class="div_style"><textarea class="switch_textarea"><img src="http://img.cheshi-img.com/product/1_720/1957/4bdfd21fb42bc.jpg" /></textarea></div>
</body>
</html>
测试页面的html代码中将所有要载入的图片都放到了textarea标签中,其目的就是防止页面载入时这些img标签向服务器发出请求,从而实现减少不必要的请求数,实际应用中也可以将不需第一次载入的html代码放到textarea中。
PS:
有部分朋友对我在页面中是用textarea有些疑问,使用textarea的目的有两个:
1、减少页面中的DOM数量,提高页面的速度;
2、实现对页面中任意HTML内容的延迟加载,并非只是针对图片的延迟加载,对于切换页签、二级菜单等均可以作到延迟载入,这样作的好处是将浏览器对页面的解析工作分散开,提高对用户的相应速度;
有很多朋友说使用img自定义属性就可以解决这个问题,我赞同,但是这里要实现的不仅仅是对图片的延迟加载,选用哪种方案要视具体的需求而定,并不存在万能的解决方案。
做成一件事才会有机会做成另一件事,路要一步一步的走