-
Notifications
You must be signed in to change notification settings - Fork 3
/
lazyLoad.js
executable file
·171 lines (169 loc) · 4.2 KB
/
lazyLoad.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
function LazyLoad(opt){
/*** 默认配置选项 */
var default_option = {
delay:300,
pics:0
}
/** 合并用户配置项 */
var options = _extern(default_option,opt);
/**
* 初始化lazyload
*/
var init = (function(){
var delay = options['delay'];
var loadIndex = options['pics'];
// 暂时只做这个选择
var imgs = document.querySelectorAll('img[lazy-src]');
// 设定了首次加载个数
if(loadIndex){
imgs.forEach(function(item,index){
if(index <= loadIndex-1){
item.src = item.getAttribute('lazy-src');
}
});
}else{
// 激活图片平铺迭代器
loadFirstScreen(imgs,loadIndex);
}
window.addEventListener("scroll",_debounce(function(){
imgs.forEach(function(item,index){
var src = item.src;
if(!src){
var status = checkStatus(item);
if(status){
item.src = item.getAttribute('lazy-src');
}
}
});
},delay));
})(options);
/**
* 迭代加载第一屏所有图片,2018年5月3号:可以考虑使用Worker预加载
*/
function loadFirstScreen(imgs,index){
if(index >= imgs.length){ return;}
var img = new Image();
img.src = imgs[index].getAttribute('lazy-src');
img.addEventListener("load",function(){
imgs[index].src = this.src;
var status = checkStatus(imgs[index]);
if(status){
//继续迭代加载图片,直到第一屏铺满
index = index + 1;
loadFirstScreen(imgs,index);
}
});
img.addEventListener("error",function(){
imgs[index].src = '默认错误图片地址';
var status = checkStatus(imgs[index]);
if(status){
//继续迭代加载图片,直到第一屏铺满
index = index + 1;
loadFirstScreen(imgs,index);
}
});
}
/**
* 检测距离顶部的位置,2018年5🈷️3号:可以试试IntersectionObserver这个API来检测。
*/
function checkStatus(el){
/** 窗体高度 */
var SH = window.innerHeight;
/** 图片大小 */
var height = el.offsetHeight;
/** 距离视窗顶部的位置 */
var elTop = el.getBoundingClientRect().top;
/** 100是滚动时候提前的距离 */
if(elTop + height >= SH + 100){
return false;
}
return true;
}
/**
* 拷贝对象属性,这里只考虑一层数据
* @return {[obj]} [返回合并后的对象]
*/
function _extern(toTarget, fromTarget) {
var newFromTarget = _shallowCopy(fromTarget);
var newToTarget = _shallowCopy(toTarget);
var keys = Object.keys(fromTarget);
keys.forEach(function(item, index, arry) {
newToTarget[item] = newFromTarget[item];
});
return newToTarget;
}
/**
* 复制一个对象自身的可枚举属性
* @param {[obj]} obj [对象]
* @return {[obj]} [对象]
*/
function _shallowCopy(obj){
var result = null;
result = iterator(obj);
return result;
}
/**
* 克隆对象迭代器
* @param {[type]} obj [对象]
* @return {[type]} [对象]
*/
function iterator(obj){
var newObj = Object.create({});
for(var i in obj){
if(obj.hasOwnProperty(i)){
var type = Object.prototype.toString.call(obj[i]);
switch (type){
case "[object Array]":
var newArry = [];
obj[i].forEach(function(item,index){
newArry[index] = item;
});
newObj[i] = newArry;
break;
case "[object Object]":
newObj[i] = iterator(obj[i]);
break;
case "[object Number]":
newObj[i] = obj[i];
break;
case "[object String]":
newObj[i] = obj[i];
break;
case "[object Function]":
newObj[i] = obj[i];
break;
case "[object HTMLDocument]":
newObj[i] = obj[i];
break;
default:
console.log("未处理类型,修改上方代码...");
break;
}
}
}
return newObj;
}
/**
* 防抖处理
*/
function _debounce(func,wait){
var timeout, args, context, timestamp;
var later = function(){
var last = Date.now()-timestamp;
if(last < wait && last > 0){
timeout = setTimeout(later, wait - last);
}else{
timeout = null;
func.apply(context, args);
if (!timeout) context = args = null;
}
}
return function(){
context = this;
args = arguments;
timestamp = Date.now();
// 如果延时不存在,重新设定延时
if(!timeout){ timeout = setTimeout(later,wait)};
}
}
}