UNPKG

8.46 kBJavaScriptView Raw
1import PinchZoom from './pinch-zoom.js';
2
3var Preview = function Preview(params) {
4 if (!window._seeds_lang) window._seeds_lang = {}; // 国际化数据
5 /* ----------------------
6 Model
7 ---------------------- */
8 var defaults = {
9 src: '', // 图片地址
10 layerHTML: '',
11
12 hash: 's_preview',
13 hashReplace: /(isFromApp=\w+)&?/, // 需要被替换的字符, 因为此地址字段会影响preview返回
14 route: true,
15
16 mask: null,
17 maskClass: 'preview-mask',
18 maskActiveClass: 'active',
19
20 showHeader: false,
21 headerClass: 'preview-header',
22 headerBackClass: 'preview-header-back',
23
24 containerClass: 'preview-container',
25
26 wrapperClass: 'preview-wrapper',
27
28 layerClass: 'preview-layer',
29
30 clickDelay: 300
31 /*
32 Callbacks:
33 onClick: function(Preview)
34 onClickBack: function(Preview)
35 onSuccess: function(Preview)
36 onError: function(Preview)
37 onShowSuccess: function(Preview)
38 onShowError: function(Preview)
39 */
40 };
41 params = params || {};
42 for (var def in defaults) {
43 if (params[def] === undefined) {
44 params[def] = defaults[def];
45 }
46 }
47 var s = this;
48 s.params = params;
49 /* ----------------------
50 Model Method
51 ---------------------- */
52 s.setSrc = function (src) {
53 if (src) {
54 s.params.src = src;
55 }
56 };
57 s.setLayerHTML = function (layerHTML) {
58 if (layerHTML) {
59 s.params.layerHTML = layerHTML;
60 }
61 };
62 s.setOnSuccess = function (onSuccess) {
63 if (onSuccess) {
64 s.params.onSuccess = onSuccess;
65 }
66 };
67 s.setOnError = function (onError) {
68 if (onError) {
69 s.params.onError = onError;
70 }
71 };
72 // 创建预览层
73 s.mask = typeof s.params.mask === 'string' ? document.querySelector(s.params.mask) : s.params.mask;
74 s.header = null;
75 s.headerBack = null;
76 s.container = null;
77 s.img = null;
78 s.createPreview = function (img, layerHTML) {
79 if (!s.mask) {
80 s.mask = document.createElement('div');
81 s.mask.setAttribute('class', s.params.maskClass);
82
83 s.header = document.createElement('div');
84 s.header.setAttribute('class', s.params.headerClass);
85
86 s.headerBack = document.createElement('div');
87 s.headerBack.setAttribute('class', s.params.headerBackClass);
88 s.headerBack.addEventListener('click', s.onClickBack, false);
89
90 s.header.appendChild(s.headerBack);
91
92 s.container = document.createElement('div');
93 s.container.setAttribute('class', s.params.containerClass);
94
95 s.mask.appendChild(s.header);
96 s.mask.appendChild(s.container);
97 s.mask.addEventListener('click', s.onClick, false);
98 document.body.appendChild(s.mask);
99 } else {
100 s.mask.addEventListener('click', s.onClick, false);
101
102 s.header = s.mask.querySelector('.' + s.params.headerClass);
103 s.headerBack = s.mask.querySelector('.' + s.params.headerBackClass);
104 s.headerBack.addEventListener('click', s.onClickBack, false);
105
106 s.container = s.mask.querySelector('.' + s.params.containerClass);
107
108 s.container.innerHTML = '';
109 }
110 if (s.params.showHeader === false) s.header.style.display = 'none';
111
112 // 构建图片
113 s.img = img;
114 s.container.appendChild(s.img);
115
116 // 构建浮层
117 s.container.innerHTML = s.container.innerHTML + layerHTML;
118 };
119 // 删除预览层
120 s.removePreview = function () {
121 if (s.mask) document.body.removeChild(s.mask);
122 s.mask = null;
123 s.header = null;
124 s.headerBack = null;
125 s.container = null;
126 s.img = null;
127 };
128 // 路径是否合法, true为有效, false为无效
129 s.validSrc = null;
130 // 缩放类PinchZoom
131 s.PinchZoom = null;
132 // 更新
133 s.update = function () {
134 if (!s.params.src) {
135 s.validSrc = false; // 图片地址无效
136 return;
137 }
138 s.removePreview();
139 var img = new Image();
140 img.src = s.params.src;
141 img.addEventListener('load', function () {
142 if (img.width > img.height) {
143 // 宽图
144 img.style.height = '100%';
145 } else {
146 // 高图
147 img.style.width = '100%';
148 }
149 s.createPreview(img, s.params.layerHTML);
150 s.validSrc = true; // 图片地址有效
151 // PinchZoom
152 s.PinchZoom = new PinchZoom(s.container, {
153 onZoomUpdate: function onZoomUpdate() {
154 if (s.clickTimeout) {
155 window.clearTimeout(s.clickTimeout);
156 s.clickTimeout = null;
157 }
158 },
159 onDragUpdate: function onDragUpdate() {
160 if (s.clickTimeout) {
161 window.clearTimeout(s.clickTimeout);
162 s.clickTimeout = null;
163 }
164 }
165 });
166
167 // 因为PinchZoom update方法并不会重置尺寸, 因此每次都需要重新new, 如果后期PinchZoom提供reset方法时则可以使用reset方法重置, 并且无须再次s.createPreview
168 // if (!s.PinchZoom) {
169 // s.PinchZoom = new PinchZoom(s.container, {
170 // onZoomUpdate: function () {
171 // if (s.clickTimeout) {
172 // window.clearTimeout(s.clickTimeout)
173 // s.clickTimeout = null
174 // }
175 // },
176 // onDragUpdate: function () {
177 // if (s.clickTimeout) {
178 // window.clearTimeout(s.clickTimeout)
179 // s.clickTimeout = null
180 // }
181 // }
182 // })
183 // } else {
184 // s.PinchZoom.update()
185 // }
186
187 // 解决PinchZoom刚进入时白底的bug
188 setTimeout(function () {
189 s.container.style.backgroundColor = '#000';
190 }, 100);
191 // Callback
192 if (s.params.onSuccess) s.params.onSuccess(s);
193 }, false);
194 img.addEventListener('error', function () {
195 s.validSrc = false; // 图片地址无效
196 // Callback
197 if (s.params.onError) s.params.onError(s);
198 }, false);
199 };
200 s.update();
201 /* ----------------------
202 Method
203 ---------------------- */
204 // 路由控制
205 s.addHash = function () {
206 if (!s.params.route) return;
207 var href = window.location.href;
208 if (href.indexOf(s.params.hash) !== -1) return;
209
210 if (href.indexOf('#') !== -1) {
211 // 有#号, 拼#后面
212 if (s.params.hashReplace.test(href)) {
213 // 如果有isFromApp, 则替换为空 (没有#号则不能替换,否则在真机上会闪屏刷新)
214 href = href.replace(RegExp.$1, '');
215 }
216 href = href + (href.indexOf('?') !== -1 ? '&' : '?') + s.params.hash;
217 } else {
218 // 没有#号, 增加#+hash
219 href = href + '#' + s.params.hash;
220 }
221 window.location.href = href;
222 };
223 s.removeHash = function () {
224 if (!s.params.route) return;
225 if (window.location.href.indexOf(s.params.hash) !== -1) {
226 window.history.go(-1);
227 }
228 };
229 // 隐藏预览
230 s.hideMask = function () {
231 s.mask.classList.remove(s.params.maskActiveClass);
232 };
233 s.hide = function () {
234 s.removeHash(); // 删除hash
235 s.hideMask();
236 };
237 // 显示预览
238 s.showMask = function () {
239 s.mask.classList.add(s.params.maskActiveClass);
240 };
241 s.show = function () {
242 if (s.validSrc) {
243 if (s.params.onShowSuccess) s.params.onShowSuccess(s);
244 s.addHash(); // 增加hash
245 s.showMask();
246 } else {
247 if (s.params.onShowError) s.params.onShowError(s, window._seeds_lang['hint_image_failed_to_load'] || '图片加载失败');
248 }
249 };
250 /* --------------------
251 Events
252 -------------------- */
253 s.events = function (detach) {
254 var action = detach ? 'removeEventListener' : 'addEventListener';
255 if (s.params.route) {
256 window[action]('popstate', s.onPopstate, false);
257 }
258 };
259 // attach、dettach事件
260 s.attach = function (event) {
261 s.events();
262 };
263 s.detach = function (event) {
264 s.events(true);
265 };
266 s.onPopstate = function () {
267 if (window.location.href.indexOf(s.params.hash) === -1) {
268 // 应当不显示
269 if (s.mask.classList.contains(s.params.maskActiveClass)) {
270 s.hideMask();
271 }
272 } else {
273 // 应当显示
274 s.showMask();
275 }
276 };
277 s.clickTimeout = null;
278 s.onClick = function () {
279 if (s.clickTimeout) {
280 window.clearTimeout(s.clickTimeout);
281 s.clickTimeout = null;
282 }
283 s.clickTimeout = window.setTimeout(function () {
284 if (s.params.onClick) s.params.onClick(s);else s.hide();
285 }, s.params.clickDelay);
286 };
287 s.onClickBack = function () {
288 if (s.params.onClickBack) s.params.onClickBack(s);else s.hide();
289 };
290 // 主函数
291 s.init = function () {
292 s.attach();
293 };
294
295 s.init();
296};
297
298export default Preview;
\No newline at end of file