UNPKG

6.8 kBJavaScriptView Raw
1// require [PrototypeString.js] clearProtocol()
2// ImgLazy 图片预加载
3import DB from './../DB';
4
5var ImgLazy = function ImgLazy(params) {
6 /* --------------------
7 Model
8 -------------------- */
9 var defaults = {
10 overflowContainer: document.body,
11 load: 'scroll', // scroll 滚动加载 | queue 队列加载 | all 全部加载
12 threshold: 300, // 滚动加载时,显示区域扩张上下像素
13 loadAttr: 'data-load-src', // 加载地址
14 errorAttr: 'data-error-src', // 错误地址
15 completeAttr: 'data-complete' // 完成加载, data-complete=0代表加载错误, =1代码加载正确
16 };
17 params = params || {};
18 for (var def in defaults) {
19 if (params[def] === undefined) {
20 params[def] = defaults[def];
21 }
22 }
23 var s = this;
24 s.params = params;
25 // Container
26 s.overflowContainer = typeof s.params.overflowContainer === 'string' ? document.querySelector(s.params.overflowContainer) : s.params.overflowContainer;
27 if (!s.overflowContainer) {
28 console.log('SeedsUI Error : Dragrefresh overflowContainer不存在,请检查页面中是否有此元素');
29 return;
30 }
31 // 所有图片
32 s.imgs = [];
33 // 记录滚动位置
34 s.scrollTop = 0;
35 /* --------------------
36 Method
37 -------------------- */
38 // 获得头部位置
39 s.getOffsetTop = function (el) {
40 var offsetTop = el.offsetTop;
41 if (el.offsetParent != null) offsetTop += s.getOffsetTop(el.offsetParent);
42
43 return offsetTop;
44 };
45 // 元素是否在显示区域内
46 s.isInScreen = function (el) {
47 var offsetTop = s.getOffsetTop(el);
48 if (offsetTop > s.scrollTop - s.params.threshold && offsetTop < parseInt(s.scrollTop, 10) + parseInt(window.innerHeight, 10)) {
49 return true;
50 }
51 return false;
52 };
53 // 浏览器已加载图片
54 s.completeList = [];
55 s.updateCompleteList = function (src) {
56 s.completeList = DB.getSession('seedsui_imglazy_complete_list') || [];
57 if (src && typeof src === 'string') {
58 s.completeList.push(src.clearProtocol());
59 DB.setSession('seedsui_imglazy_complete_list', s.completeList);
60 }
61 };
62 s.updateCompleteList();
63 // 是否已加载
64 s.isComplete = function (src) {
65 if (src && typeof src === 'string' && s.completeList.indexOf(src.clearProtocol()) !== -1) {
66 return true;
67 }
68 return false;
69 };
70 /* --------------------
71 Events
72 -------------------- */
73 s.events = function (detach) {
74 var action = detach ? 'removeEventListener' : 'addEventListener';
75 if (s.params.load === 'scroll') {
76 var scrollTarget = s.overflowContainer === document.body ? window : s.overflowContainer;
77 scrollTarget[action]('scroll', s.onScroll, false);
78 }
79 };
80 s.attach = function () {
81 s.events();
82 };
83 s.detach = function () {
84 s.events(false);
85 };
86 // 加载完成事件
87 s.onLoad = function (e) {
88 var target = e.target;
89 var imgTarget = target.$el;
90 imgTarget.setAttribute(s.params.completeAttr, '1');
91 // 图片加载完成后记录到seesion中
92 s.updateCompleteList(target.src);
93
94 // 渲染图片
95 s.render(imgTarget, target.src);
96 // console.log('加载图片' + target.src)
97 };
98 // 渲染图片
99 s.render = function (target, src) {
100 if (target.tagName === 'IMG') {
101 target.src = src;
102 } else {
103 target.style.backgroundImage = 'url(' + src + ')';
104 }
105 };
106 // 加载失败事件
107 s.onError = function (e) {
108 var target = e.target;
109 var imgTarget = target.$el;
110 imgTarget.setAttribute(s.params.completeAttr, '0');
111 if (target.errorSrc) {
112 // 渲染图片
113 s.render(imgTarget, target.errorSrc);
114 }
115 // console.log('错误图片' + target.src)
116 };
117 // 滚动完成事件 (如果300毫秒内滚动条没变,则视为onScrollEnd)
118 var timer;
119 var millisec = 300;
120 s.getScrollTop = function () {
121 return s.overflowContainer === document.body ? document.documentElement.scrollTop : s.overflowContainer.scrollTop;
122 };
123 s.onScroll = function () {
124 s.scrollTop = s.getScrollTop();
125 if (timer) {
126 clearTimeout(timer);
127 }
128 timer = setTimeout(function () {
129 if (s.scrollTop === s.getScrollTop()) {
130 s.onScrollEnd();
131 clearTimeout(timer);
132 return;
133 }
134 timer = null;
135 }, millisec);
136 };
137 s.onScrollEnd = function () {
138 console.log('停止滚动');
139 s.load();
140 };
141 /* --------------------
142 Init
143 -------------------- */
144 s.load = function () {
145 // 更新已加载的图片
146 s.updateCompleteList();
147
148 // 获取所有需要加载的图片
149 s.imgs = [].slice.call(s.overflowContainer.querySelectorAll('[' + s.params.loadAttr + ']')).filter(function (n) {
150 if (n.getAttribute(s.params.loadAttr)) return true;
151 return false;
152 });
153
154 // 队列加载
155 if (s.params.load === 'queue') {
156 s.queue(0);
157 return;
158 }
159
160 // 懒人加载
161 for (var i = 0; i < s.imgs.length; i++) {
162 // 图片路径和裂图路径
163 var loadSrc = s.imgs[i].getAttribute(s.params.loadAttr);
164 var errorSrc = s.imgs[i].getAttribute(s.params.imgErrorAttr) || '';
165 // 已加载的图片不需要再次加载
166 if (s.isComplete(loadSrc)) {
167 s.render(s.imgs[i], loadSrc); // 渲染图片
168 continue;
169 }
170
171 var flag = true;
172 if (s.params.load === 'scroll') flag = s.isInScreen(s.imgs[i]); // 滚动加载
173 if (flag && !s.imgs[i].getAttribute(s.params.completeAttr)) {
174 console.log('加载' + loadSrc);
175 var image = new Image();
176 image.$el = s.imgs[i];
177 image.src = loadSrc;
178 image.errorSrc = errorSrc;
179 image.addEventListener('load', s.onLoad, false);
180 image.addEventListener('error', s.onError, false);
181 }
182 }
183 };
184 // 队列加载
185 s.queue = function (i) {
186 // 图片路径和裂图路径
187 var loadSrc = s.imgs[i].getAttribute(s.params.loadAttr);
188 var errorSrc = s.imgs[i].getAttribute(s.params.imgErrorAttr) || '';
189 // 已加载的图片不需要再次加载
190 if (s.isComplete(loadSrc)) {
191 s.render(s.imgs[i], loadSrc); // 渲染图片
192 s.queue(i++);
193 return;
194 }
195 // 加载
196 if (s.imgs[i].getAttribute(s.params.completeAttr)) {
197 i++;
198 }
199 if (!s.imgs[i]) {
200 return;
201 }
202
203 var image = new Image();
204 image.$el = s.imgs[i];
205 image.src = loadSrc;
206 image.errorSrc = errorSrc;
207 image.addEventListener('load', function (e) {
208 console.log('加载第' + i + '张');
209 s.onLoad(e);
210 s.queue(i++);
211 }, false);
212 image.addEventListener('error', function (e) {
213 console.log('第' + i + '张加载失败');
214 s.onError(e);
215 s.queue(i++);
216 }, false);
217 };
218 s.update = function () {
219 if (s.params.load === 'scroll') {
220 s.detach();
221 s.attach();
222 }
223 };
224 s.update();
225};
226
227export default ImgLazy;
\No newline at end of file