滚动加载图片(懒加载)实现原理
//扩展为jquery插件;使用方法:$("selector").scrollLoad({ 参数在代码中有说明 })http://www.tuicool.com/articles/rUjIZzb
1 (function($) {
2 $.fn.scrollLoading = function(options) {
3 var defaults = {
4 // 在html标签中存放的属性名称;
5 attr: "data-url",
6 // 父元素默认为window
7 container: window,
8 callback: $.noop
9 };
10 // 不管有没有传入参数,先合并再说;
11 var params = $.extend({}, defaults, options || {});
12 // 把父元素转为jquery对象;
13 var container = $(params.container);
14 // 新建一个数组,然后调用each方法,用于存储每个dom对象相关的数据;
15 params.cache = [];
16 $(this).each(function() {
17 // 取出jquery对象中每个dom对象的节点类型,取出每个dom对象上设置的图片路径
18 var node = this.nodeName.toLowerCase(), url = $(this).attr(params["attr"]);
19 //重组,把每个dom对象上的属性存为一个对象;
20 var data = {
21 obj: $(this),
22 tag: node,
23 url: url
24 };
25 // 把这个对象加到一个数组中;
26 params.cache.push(data);
27 });
28
29 var callback = function(call) {
30 if ($.isFunction(params.callback)) {
31 params.callback.call(call);
32 }
33 };
34
35 //每次触发滚动事件时,对每个dom元素与container元素进行位置判断,如果满足条件,就把路径赋予这个dom元素!
36 var loading = function() {
37 // 获取父元素的高度
38 var contHeight = container.outerHeight();
39 var contWidth = container.outerWidth();
40
41 // 获取父元素相对于文档页顶部的距离,这边要注意了,分为以下两种情况;
42 if (container.get(0) === window) {
43 // 第一种情况父元素为window,获取浏览器滚动条已滚动的距离;$(window)没有offset()方法;
44 var contop = $(window).scrollTop();
45 var conleft = $(window).scrollLeft();
46 } else {
47 // 第二种情况父元素为非window元素,获取它的滚动条滚动的距离;
48 var contop = container.offset().top;
49 var conleft = container.offset().left;
50 }
51
52 $.each(params.cache, function(i, data) {
53 var o = data.obj, tag = data.tag, url = data.url, post, posb, posl, posr;
54 if (o) {
55 //对象顶部与文档顶部之间的距离,如果它小于父元素底部与文档顶部的距离,则说明垂直方向上已经进入可视区域了;
56 post = o.offset().top - (contop + contHeight);
57 //对象底部与文档顶部之间的距离,如果它大于父元素顶部与文档顶部的距离,则说明垂直方向上已经进入可视区域了;
58 posb = o.offset().top + o.height() - contop;
59
60 // 水平方向上同理;
61 posl = o.offset().left - (conleft + contWidth);
62 posr = o.offset().left + o.width() - conleft;
63
64 // 只有当这个对象是可视的,并且这四个条件都满足时,才能给这个对象赋予图片路径;
65 if ( o.is(':visible') && (post < 0 && posb > 0) && (posl < 0 && posr > 0) ) {
66 if (url) {
67 //在浏览器窗口内
68 if (tag === "img") {
69 //设置图片src
70 callback(o.attr("src", url));
71 } else {
72 // 设置除img之外元素的背景url
73 callback(o.css("background-image", "url("+ url +")"));
74 }
75 } else {
76 // 无地址,直接触发回调
77 callback(o);
78 }
79 // 给对象设置完图片路径之后,把params.cache中的对象给清除掉;对象再进入可视区,就不再进行重复设置了;
80 data.obj = null;
81 }
82 }
83 });
84 };
85 //加载完毕即执行
86 loading();
87 //滚动执行
88 container.bind("scroll", loading);
89 };
90 })(jQuery);