fastman2 3.0.0-alpha.1 → 3.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actionsheetman.js +1 -96
- package/alertman.js +1 -79
- package/annotationman.js +17 -2912
- package/baseman.js +1 -115
- package/blankpageman.js +1 -171
- package/cascadepickerman.js +1 -322
- package/confirmman.js +1 -87
- package/coreman.js +3 -2182
- package/cryptoman.js +2 -8931
- package/datetimepickerman.js +1 -181
- package/domman.js +1 -2759
- package/eventemitterman.js +1 -112
- package/fileuploadman.js +1 -2970
- package/formvalidateman.js +1 -335
- package/jsbridgeman.js +1 -992
- package/lazyloadman.js +1 -133
- package/loadingman.js +1 -81
- package/modalman.js +1 -264
- package/mutationobserverman.js +1 -356
- package/package.json +1 -1
- package/passguardman.js +1 -1722
- package/persistman.js +1 -60
- package/pickerman.js +1 -680
- package/popupman.js +1 -61
- package/postman.js +1 -1649
- package/preloadman.js +2 -8760
- package/resultpageman.js +1 -153
- package/routerman.js +1 -1201
- package/scrollman-infiniteRefresh.js +1 -117
- package/scrollman-pullDownRefresh.js +1 -302
- package/scrollman.js +2 -2567
- package/storeman.js +1 -585
- package/swiperman.js +1 -4702
- package/swiperoldman.js +1 -3005
- package/tabman.js +1 -145
- package/tipman.js +1 -110
- package/toastman.js +1 -78
- package/toolman.js +1 -22
- package/whenman.js +1 -774
- package/wsman.js +1 -7624
package/routerman.js
CHANGED
|
@@ -1,1201 +1 @@
|
|
|
1
|
-
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
-
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
-
module.exports = factory();
|
|
4
|
-
else if(typeof define === 'function' && define.amd)
|
|
5
|
-
define([], factory);
|
|
6
|
-
else if(typeof exports === 'object')
|
|
7
|
-
exports["fastman"] = factory();
|
|
8
|
-
else
|
|
9
|
-
root["fastman"] = factory();
|
|
10
|
-
})(this, function() {
|
|
11
|
-
return webpackJsonpfastman([7],{
|
|
12
|
-
|
|
13
|
-
/***/ 150:
|
|
14
|
-
/***/ (function(module, exports, __webpack_require__) {
|
|
15
|
-
|
|
16
|
-
"use strict";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Object.defineProperty(exports, "__esModule", {
|
|
20
|
-
value: true
|
|
21
|
-
});
|
|
22
|
-
/**
|
|
23
|
-
* Created by dfzq on 2017/3/4.
|
|
24
|
-
*/
|
|
25
|
-
/**
|
|
26
|
-
* 获取 url 的 fragment(即 hash 中去掉 # 的剩余部分)
|
|
27
|
-
*
|
|
28
|
-
* 如果没有则返回空字符串
|
|
29
|
-
* 如: http://example.com/path/?query=d#123 => 123
|
|
30
|
-
*
|
|
31
|
-
* @param {String} url url
|
|
32
|
-
* @returns {String}
|
|
33
|
-
*/
|
|
34
|
-
var getUrlFragment = exports.getUrlFragment = function getUrlFragment(url) {
|
|
35
|
-
var hashIndex = url.indexOf('#');
|
|
36
|
-
//return hashIndex === -1 ? '' : url.slice(hashIndex + 1);
|
|
37
|
-
return hashIndex === -1 ? '/' : url.slice(hashIndex + 1);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 获取一个链接相对于当前页面的绝对地址形式
|
|
42
|
-
*
|
|
43
|
-
* 假设当前页面是 http://a.com/b/c
|
|
44
|
-
* 那么有以下情况:
|
|
45
|
-
* d => http://a.com/b/d
|
|
46
|
-
* /e => http://a.com/e
|
|
47
|
-
* #1 => http://a.com/b/c#1
|
|
48
|
-
* http://b.com/f => http://b.com/f
|
|
49
|
-
*
|
|
50
|
-
* @param {String} url url
|
|
51
|
-
* @returns {String}
|
|
52
|
-
*/
|
|
53
|
-
var getAbsoluteUrl = exports.getAbsoluteUrl = function getAbsoluteUrl(url) {
|
|
54
|
-
var link = document.createElement('a');
|
|
55
|
-
link.setAttribute('href', url);
|
|
56
|
-
var absoluteUrl = link.href;
|
|
57
|
-
link = null;
|
|
58
|
-
return absoluteUrl;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 获取一个 url 的基本部分,即不包括 hash
|
|
63
|
-
*
|
|
64
|
-
* @param {String} url url
|
|
65
|
-
* @returns {String}
|
|
66
|
-
*/
|
|
67
|
-
var getBaseUrl = exports.getBaseUrl = function getBaseUrl(url) {
|
|
68
|
-
var hashIndex = url.indexOf('#');
|
|
69
|
-
return hashIndex === -1 ? url.slice(0) : url.slice(0, hashIndex);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 把一个字符串的 url 转为一个可获取其 base 和 fragment 等的对象
|
|
74
|
-
*
|
|
75
|
-
* @param {String} url url
|
|
76
|
-
* @returns {UrlObject}
|
|
77
|
-
*/
|
|
78
|
-
var toUrlObject = exports.toUrlObject = function toUrlObject(url) {
|
|
79
|
-
var fullUrl = getAbsoluteUrl(url),
|
|
80
|
-
baseUrl = getBaseUrl(fullUrl),
|
|
81
|
-
fragment = getUrlFragment(url);
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
base: baseUrl,
|
|
85
|
-
full: fullUrl,
|
|
86
|
-
original: url,
|
|
87
|
-
fragment: fragment
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 判断浏览器是否支持 sessionStorage,支持返回 true,否则返回 false
|
|
93
|
-
* @returns {Boolean}
|
|
94
|
-
*/
|
|
95
|
-
var supportStorage = exports.supportStorage = function supportStorage() {
|
|
96
|
-
var mod = 'ob.router.storage.ability';
|
|
97
|
-
try {
|
|
98
|
-
sessionStorage.setItem(mod, mod);
|
|
99
|
-
sessionStorage.removeItem(mod);
|
|
100
|
-
return true;
|
|
101
|
-
} catch (e) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
/***/ }),
|
|
107
|
-
|
|
108
|
-
/***/ 235:
|
|
109
|
-
/***/ (function(module, exports, __webpack_require__) {
|
|
110
|
-
|
|
111
|
-
module.exports = __webpack_require__(52);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
/***/ }),
|
|
115
|
-
|
|
116
|
-
/***/ 52:
|
|
117
|
-
/***/ (function(module, exports, __webpack_require__) {
|
|
118
|
-
|
|
119
|
-
"use strict";
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
Object.defineProperty(exports, "__esModule", {
|
|
123
|
-
value: true
|
|
124
|
-
});
|
|
125
|
-
/**
|
|
126
|
-
* Created by dfzq on 2017/2/9.
|
|
127
|
-
*/
|
|
128
|
-
var Util = __webpack_require__(150);
|
|
129
|
-
var Version = __webpack_require__(58);
|
|
130
|
-
// require("./native.history")
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (!window.CustomEvent) {
|
|
134
|
-
window.CustomEvent = function (type, config) {
|
|
135
|
-
config = config || { bubbles: false, cancelable: false, detail: undefined };
|
|
136
|
-
var e = document.createEvent('CustomEvent');
|
|
137
|
-
e.initCustomEvent(type, config.bubbles, config.cancelable, config.detail);
|
|
138
|
-
return e;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
window.CustomEvent.prototype = window.Event.prototype;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
var EVENTS = {
|
|
145
|
-
pageLoadStart: 'pageLoadStart', // ajax 开始加载新页面前
|
|
146
|
-
pageLoadCancel: 'pageLoadCancel', // 取消前一个 ajax 加载动作后
|
|
147
|
-
pageLoadError: 'pageLoadError', // ajax 加载页面失败后
|
|
148
|
-
pageLoadComplete: 'pageLoadComplete', // ajax 加载页面完成后(不论成功与否)
|
|
149
|
-
pageAnimationStart: 'pageAnimationStart', // 动画切换 page 前
|
|
150
|
-
pageAnimationEnd: 'pageAnimationEnd', // 动画切换 page 结束后
|
|
151
|
-
beforePageRemove: 'beforePageRemove', // 移除旧 document 前(适用于非内联 page 切换)
|
|
152
|
-
pageRemoved: 'pageRemoved', // 移除旧 document 后(适用于非内联 page 切换)
|
|
153
|
-
beforePageSwitch: 'beforePageSwitch', // page 切换前,在 pageAnimationStart 前,beforePageSwitch 之后会做一些额外的处理才触发 pageAnimationStart
|
|
154
|
-
pageInit: 'pageInitInternal' // 目前是定义为一个 page 加载完毕后(实际和 pageAnimationEnd 等同)
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
var routerConfig = {
|
|
158
|
-
sectionGroupClass: 'page-group',
|
|
159
|
-
// 表示是当前 page 的 class
|
|
160
|
-
curPageClass: 'page-current',
|
|
161
|
-
// 用来辅助切换时表示 page 是 visible 的,
|
|
162
|
-
// 之所以不用 curPageClass,是因为 page-current 已被赋予了「当前 page」这一含义而不仅仅是 display: block
|
|
163
|
-
// 并且,别的地方已经使用了,所以不方便做变更,故新增一个
|
|
164
|
-
visiblePageClass: 'page-visible',
|
|
165
|
-
// 表示是 page 的 class,注意,仅是标志 class,而不是所有的 class
|
|
166
|
-
pageClass: 'page'
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
var DIRECTION = {
|
|
170
|
-
leftToRight: 'from-left-to-right',
|
|
171
|
-
rightToLeft: 'from-right-to-left'
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
var theHistory = $.device.hasNativeHistory ? window.history : History;
|
|
175
|
-
/**
|
|
176
|
-
* 判断对象是否为空(没有属性)
|
|
177
|
-
* */
|
|
178
|
-
var isObjectEmpty = function isObjectEmpty(obj) {
|
|
179
|
-
for (var key in obj) {
|
|
180
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return true;
|
|
185
|
-
};
|
|
186
|
-
var getHistoryState = function getHistoryState() {
|
|
187
|
-
// 针对不同的 兼容性 获取 history 的state
|
|
188
|
-
if ($.device.hasNativeHistory) {
|
|
189
|
-
return theHistory.state; // 没有为 null
|
|
190
|
-
}
|
|
191
|
-
var state = theHistory.getState().data;
|
|
192
|
-
// 兼容的 history 初始时 值为 {} 设置为null 与原来的 情况保持一致
|
|
193
|
-
if (isObjectEmpty(state)) {
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
return state;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* 路由构造函数
|
|
201
|
-
* @constructor 构造器
|
|
202
|
-
*/
|
|
203
|
-
var Router = function Router() {
|
|
204
|
-
this.sessionNames = {
|
|
205
|
-
currentState: 'application.router.currentState',
|
|
206
|
-
maxStateId: 'application.router.maxStateId'
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
// 初始化history的state并做了一些缓存工作
|
|
210
|
-
this._init();
|
|
211
|
-
this.xhr = null;
|
|
212
|
-
// Hash对应的VDom
|
|
213
|
-
this.vdoms = {};
|
|
214
|
-
// Hash对应的viewId
|
|
215
|
-
this.hash2ViewId = {};
|
|
216
|
-
// 路由是否由popstate引起
|
|
217
|
-
this.popstateFlag = false;
|
|
218
|
-
|
|
219
|
-
// 这块的声明已被移植到核心库的router模块中
|
|
220
|
-
//window.addEventListener('popstate', this._onPopState.bind(this));
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* 初始化
|
|
225
|
-
*
|
|
226
|
-
* - 把当前文档内容缓存起来
|
|
227
|
-
* - 查找默认展示的块内容,查找顺序如下
|
|
228
|
-
* 1. id 是 url 中的 fragment 的元素
|
|
229
|
-
* 2. 有当前块 class 标识的第一个元素
|
|
230
|
-
* 3. 第一个块
|
|
231
|
-
* - 初始页面 state 处理
|
|
232
|
-
*
|
|
233
|
-
* @private
|
|
234
|
-
*/
|
|
235
|
-
Router.prototype._init = function () {
|
|
236
|
-
|
|
237
|
-
this.$view = $('body');
|
|
238
|
-
|
|
239
|
-
// 用来保存 document 的 map
|
|
240
|
-
this.cache = {};
|
|
241
|
-
var $doc = $(document);
|
|
242
|
-
var currentUrl = location.href;
|
|
243
|
-
// 根据absoluteUrl将当前页面的document和page-group的dom缓存起来
|
|
244
|
-
this._saveDocumentIntoCache($doc, currentUrl);
|
|
245
|
-
|
|
246
|
-
var curPageId;
|
|
247
|
-
|
|
248
|
-
var currentUrlObj = Util.toUrlObject(currentUrl);
|
|
249
|
-
var $allSection = $doc.find('.' + routerConfig.pageClass);
|
|
250
|
-
var $visibleSection = $doc.find('.' + routerConfig.curPageClass);
|
|
251
|
-
var $curVisibleSection = $visibleSection.eq(0);
|
|
252
|
-
var $hashSection;
|
|
253
|
-
|
|
254
|
-
// if (currentUrlObj.fragment) {
|
|
255
|
-
// $hashSection = $doc.find('#' + currentUrlObj.fragment);
|
|
256
|
-
// }
|
|
257
|
-
// if ($hashSection && $hashSection.length) {
|
|
258
|
-
// $visibleSection = $hashSection.eq(0);
|
|
259
|
-
// }
|
|
260
|
-
// else if (!$visibleSection.length) {
|
|
261
|
-
// $visibleSection = $allSection.eq(0);
|
|
262
|
-
// }
|
|
263
|
-
if (!$visibleSection.length) {
|
|
264
|
-
$visibleSection = $allSection.eq(0);
|
|
265
|
-
}
|
|
266
|
-
// 如果当前page没有定义id,则随机产生id
|
|
267
|
-
if (!$visibleSection.attr('id')) {
|
|
268
|
-
$visibleSection.attr('id', getHistoryState() == null ? this._generateRandomId() : getHistoryState().pageId);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if ($curVisibleSection.length && $curVisibleSection.attr('id') !== $visibleSection.attr('id')) {
|
|
272
|
-
// 在 router 到 inner page 的情况下,刷新(或者直接访问该链接)
|
|
273
|
-
// 直接切换 class 会有「闪」的现象,或许可以采用 animateSection 来减缓一下
|
|
274
|
-
$curVisibleSection.removeClass(routerConfig.curPageClass);
|
|
275
|
-
$visibleSection.addClass(routerConfig.curPageClass);
|
|
276
|
-
} else {
|
|
277
|
-
$visibleSection.addClass(routerConfig.curPageClass);
|
|
278
|
-
}
|
|
279
|
-
curPageId = $visibleSection.attr('id');
|
|
280
|
-
|
|
281
|
-
// 新进入一个使用 history.state 相关技术的页面时,如果第一个 state 不 push/replace,
|
|
282
|
-
// 那么在后退回该页面时,将不触发 popState 事件
|
|
283
|
-
if (getHistoryState() === null) {
|
|
284
|
-
var curState = {
|
|
285
|
-
id: this._getNextStateId(),
|
|
286
|
-
url: Util.toUrlObject(currentUrl),
|
|
287
|
-
pageId: curPageId
|
|
288
|
-
};
|
|
289
|
-
var hash = currentUrl;
|
|
290
|
-
// 当在ie9 中使用historyjs 时 不能将 完整的url 给 replaceState 的第三个参数 会导致地址栏 以及跳转不正确
|
|
291
|
-
// 使用 "/" 来代替
|
|
292
|
-
if (!$.device.hasNativeHistory) {
|
|
293
|
-
hash = curState.url.fragment;
|
|
294
|
-
// hash = "?id=" + curState.id + "&pageId=" + curState.pageId;
|
|
295
|
-
window.__isReplaceState = true;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// 如果是 historyjs 且 url中已经有 相应标识 认为是 原地刷新 不再执行replaceState
|
|
299
|
-
if (!$.device.hasNativeHistory && /\?&_suid=.+$/.test(currentUrl)) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
theHistory.replaceState(curState, '', hash);
|
|
304
|
-
this._saveAsCurrentState(curState);
|
|
305
|
-
this._incMaxStateId();
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* 切换到 url 指定的块或文档
|
|
311
|
-
*
|
|
312
|
-
* 如果 url 指向的是当前页面,那么认为是切换块;
|
|
313
|
-
* 否则是切换文档
|
|
314
|
-
*
|
|
315
|
-
* @param {String} router 核心层的router,内部包含match和path
|
|
316
|
-
* @param {Boolean=} ignoreCache 是否强制请求不使用缓存,对 document 生效,默认是 false
|
|
317
|
-
*/
|
|
318
|
-
Router.prototype.load = function (router, ignoreCache) {
|
|
319
|
-
// if (ignoreCache === undefined) {
|
|
320
|
-
// ignoreCache = false;
|
|
321
|
-
// }
|
|
322
|
-
|
|
323
|
-
// if (this._isTheSameDocument(location.href, url)) {
|
|
324
|
-
// this._switchToSection(Util.getUrlFragment(url));
|
|
325
|
-
// } else {
|
|
326
|
-
// this._saveDocumentIntoCache($(document), location.href);
|
|
327
|
-
// this._switchToDocument(url, ignoreCache);
|
|
328
|
-
// }
|
|
329
|
-
|
|
330
|
-
// // TODO 目前只支持内联,未来可扩展外联链接方式 ...
|
|
331
|
-
// var hashId = Util.getUrlFragment(url)
|
|
332
|
-
// core模块中进行v-tree操作
|
|
333
|
-
// // 查找当前doms作用域中是否存在当前路由
|
|
334
|
-
// if (!this.vdoms[hashId])
|
|
335
|
-
// $.loadDocument(hashId)
|
|
336
|
-
// 切换页面块
|
|
337
|
-
this._switchToSection(router);
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* 调用 history.forward()
|
|
342
|
-
*/
|
|
343
|
-
Router.prototype.forward = function () {
|
|
344
|
-
theHistory.forward();
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* 调用 history.back()
|
|
349
|
-
*/
|
|
350
|
-
Router.prototype.back = function () {
|
|
351
|
-
theHistory.back();
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
//noinspection JSUnusedGlobalSymbols
|
|
355
|
-
/**
|
|
356
|
-
* @deprecated
|
|
357
|
-
*/
|
|
358
|
-
Router.prototype.loadPage = Router.prototype.load;
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* 切换显示当前文档另一个块
|
|
362
|
-
*
|
|
363
|
-
* 把新块从右边切入展示,同时会把新的块的记录用 history.pushState 来保存起来
|
|
364
|
-
*
|
|
365
|
-
* 如果已经是当前显示的块,那么不做任何处理;
|
|
366
|
-
* 如果没对应的块,那么忽略。
|
|
367
|
-
*
|
|
368
|
-
* @param {String} router 待切换router,内部包含match和path
|
|
369
|
-
* @private
|
|
370
|
-
*/
|
|
371
|
-
Router.prototype._switchToSection = function (router) {
|
|
372
|
-
var hashId = router.path;
|
|
373
|
-
var match = router.match;
|
|
374
|
-
if (!hashId) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
var $curPage = this._getCurrentSection();
|
|
379
|
-
// 根据路由规则,新页面将会是page-group的最后一个子节点
|
|
380
|
-
//$newPage = $('#' + sectionId);
|
|
381
|
-
var $newPage;
|
|
382
|
-
if (!this.hash2ViewId[match]) {
|
|
383
|
-
$newPage = this.$view.find('.' + routerConfig.pageClass).eq(-1);
|
|
384
|
-
} else {
|
|
385
|
-
$newPage = $('#' + this.hash2ViewId[match]);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// 如果已经是当前页,不做任何处理
|
|
389
|
-
if ($curPage === $newPage) {
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
this._animateSection($curPage, $newPage, DIRECTION.rightToLeft);
|
|
394
|
-
// 待切换的块未设置ID,自动生成一个随机值
|
|
395
|
-
var sectionId;
|
|
396
|
-
if (!$newPage.attr('id')) {
|
|
397
|
-
sectionId = this._generateRandomId();
|
|
398
|
-
$newPage.attr('id', sectionId);
|
|
399
|
-
} else {
|
|
400
|
-
sectionId = $newPage.attr('id');
|
|
401
|
-
}
|
|
402
|
-
this.hash2ViewId[match] = sectionId;
|
|
403
|
-
|
|
404
|
-
this._pushNewState('#' + hashId, sectionId);
|
|
405
|
-
|
|
406
|
-
// // 更新当前可见页面的node
|
|
407
|
-
// $.setNode(this.vdoms[hashId])
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* 载入显示一个新的文档
|
|
412
|
-
*
|
|
413
|
-
* - 如果有缓存,那么直接利用缓存来切换
|
|
414
|
-
* - 否则,先把页面加载过来缓存,然后再切换
|
|
415
|
-
* - 如果解析失败,那么用 location.href 的方式来跳转
|
|
416
|
-
*
|
|
417
|
-
* 注意:不能在这里以及其之后用 location.href 来 **读取** 切换前的页面的 url,
|
|
418
|
-
* 因为如果是 popState 时的调用,那么此时 location 已经是 pop 出来的 state 的了
|
|
419
|
-
*
|
|
420
|
-
* @param {String} url 新的文档的 url
|
|
421
|
-
* @param {Boolean=} ignoreCache 是否不使用缓存强制加载页面
|
|
422
|
-
* @param {Boolean=} isPushState 是否需要 pushState
|
|
423
|
-
* @param {String=} direction 新文档切入的方向
|
|
424
|
-
* @private
|
|
425
|
-
*/
|
|
426
|
-
Router.prototype._switchToDocument = function (url, ignoreCache, isPushState, direction) {
|
|
427
|
-
var baseUrl = Util.toUrlObject(url).base;
|
|
428
|
-
|
|
429
|
-
if (ignoreCache) {
|
|
430
|
-
delete this.cache[baseUrl];
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
var cacheDocument = this.cache[baseUrl];
|
|
434
|
-
var context = this;
|
|
435
|
-
|
|
436
|
-
if (cacheDocument) {
|
|
437
|
-
this._doSwitchDocument(url, isPushState, direction);
|
|
438
|
-
} else {
|
|
439
|
-
// TODO 改造成mobi中的http通讯模块 ...
|
|
440
|
-
this._loadDocument(url, {
|
|
441
|
-
success: function success($doc) {
|
|
442
|
-
try {
|
|
443
|
-
context._parseDocument(url, $doc);
|
|
444
|
-
context._doSwitchDocument(url, isPushState, direction);
|
|
445
|
-
} catch (e) {
|
|
446
|
-
location.href = url;
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
error: function error() {
|
|
450
|
-
location.href = url;
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* 利用缓存来做具体的切换文档操作
|
|
458
|
-
*
|
|
459
|
-
* - 确定待切入的文档的默认展示 section
|
|
460
|
-
* - 把新文档 append 到 view 中
|
|
461
|
-
* - 动画切换文档
|
|
462
|
-
* - 如果需要 pushState,那么把最新的状态 push 进去并把当前状态更新为该状态
|
|
463
|
-
*
|
|
464
|
-
* @param {String} url 待切换的文档的 url
|
|
465
|
-
* @param {Boolean} isPushState 加载页面后是否需要 pushState,默认是 true
|
|
466
|
-
* @param {String} direction 动画切换方向,默认是 DIRECTION.rightToLeft
|
|
467
|
-
* @private
|
|
468
|
-
*/
|
|
469
|
-
Router.prototype._doSwitchDocument = function (url, isPushState, direction) {
|
|
470
|
-
if (typeof isPushState === 'undefined') {
|
|
471
|
-
isPushState = true;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
var urlObj = Util.toUrlObject(url);
|
|
475
|
-
// 当前Document
|
|
476
|
-
var $currentDoc = this.$view.find('.' + routerConfig.sectionGroupClass);
|
|
477
|
-
// 将要animateTo的Document
|
|
478
|
-
var $newDoc = $($('<div></div>').append(this.cache[urlObj.base].$content).html());
|
|
479
|
-
|
|
480
|
-
// 确定一个 document 展示 section 的顺序
|
|
481
|
-
// 1. 与 hash 关联的 element
|
|
482
|
-
// 2. 默认的标识为 current 的 element
|
|
483
|
-
// 3. 第一个 section
|
|
484
|
-
var $allSection = $newDoc.find('.' + routerConfig.pageClass);
|
|
485
|
-
var $visibleSection = $newDoc.find('.' + routerConfig.curPageClass);
|
|
486
|
-
var $hashSection;
|
|
487
|
-
|
|
488
|
-
if (urlObj.fragment) {
|
|
489
|
-
$hashSection = $newDoc.find('#' + urlObj.fragment);
|
|
490
|
-
}
|
|
491
|
-
if ($hashSection && $hashSection.length) {
|
|
492
|
-
$visibleSection = $hashSection.eq(0);
|
|
493
|
-
} else if (!$visibleSection.length) {
|
|
494
|
-
$visibleSection = $allSection.eq(0);
|
|
495
|
-
}
|
|
496
|
-
if (!$visibleSection.attr('id')) {
|
|
497
|
-
$visibleSection.attr('id', this._generateRandomId());
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
var $currentSection = this._getCurrentSection();
|
|
501
|
-
$currentSection.trigger(EVENTS.beforePageSwitch, [$currentSection.attr('id'), $currentSection]);
|
|
502
|
-
|
|
503
|
-
$allSection.removeClass(routerConfig.curPageClass);
|
|
504
|
-
$visibleSection.addClass(routerConfig.curPageClass);
|
|
505
|
-
|
|
506
|
-
// prepend 而不 append 的目的是避免 append 进去新的 document 在后面,
|
|
507
|
-
// 其里面的默认展示的(.page-current) 的页面直接就覆盖了原显示的页面(因为都是 absolute)
|
|
508
|
-
this.$view.prepend($newDoc);
|
|
509
|
-
|
|
510
|
-
this._animateDocument($currentDoc, $newDoc, $visibleSection, direction);
|
|
511
|
-
|
|
512
|
-
if (isPushState) {
|
|
513
|
-
this._pushNewState(url, $visibleSection.attr('id'));
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
/**
|
|
518
|
-
* 判断两个 url 指向的页面是否是同一个
|
|
519
|
-
*
|
|
520
|
-
* 判断方式: 如果两个 url 的 base 形式(不带 hash 的绝对形式)相同,那么认为是同一个页面
|
|
521
|
-
*
|
|
522
|
-
* @param {String} url
|
|
523
|
-
* @param {String} anotherUrl
|
|
524
|
-
* @returns {Boolean}
|
|
525
|
-
* @private
|
|
526
|
-
*/
|
|
527
|
-
Router.prototype._isTheSameDocument = function (url, anotherUrl) {
|
|
528
|
-
return Util.toUrlObject(url).base === Util.toUrlObject(anotherUrl).base;
|
|
529
|
-
};
|
|
530
|
-
|
|
531
|
-
/**
|
|
532
|
-
* ajax 加载 url 指定的页面内容
|
|
533
|
-
*
|
|
534
|
-
* 加载过程中会发出以下事件
|
|
535
|
-
* pageLoadCancel: 如果前一个还没加载完,那么取消并发送该事件
|
|
536
|
-
* pageLoadStart: 开始加载
|
|
537
|
-
* pageLodComplete: ajax complete 完成
|
|
538
|
-
* pageLoadError: ajax 发生 error
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
* @param {String} url url
|
|
542
|
-
* @param {Object=} callback 回调函数配置,可选,可以配置 success\error 和 complete
|
|
543
|
-
* 所有回调函数的 this 都是 null,各自实参如下:
|
|
544
|
-
* success: $doc, status, xhr
|
|
545
|
-
* error: xhr, status, err
|
|
546
|
-
* complete: xhr, status
|
|
547
|
-
*
|
|
548
|
-
* @private
|
|
549
|
-
*/
|
|
550
|
-
Router.prototype._loadDocument = function (url, callback) {
|
|
551
|
-
// 并发操作考虑
|
|
552
|
-
if (this.xhr && this.xhr.readyState < 4) {
|
|
553
|
-
this.xhr.onreadystatechange = function () {};
|
|
554
|
-
this.xhr.abort();
|
|
555
|
-
this.dispatch(EVENTS.pageLoadCancel);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
this.dispatch(EVENTS.pageLoadStart);
|
|
559
|
-
|
|
560
|
-
callback = callback || {};
|
|
561
|
-
var self = this;
|
|
562
|
-
|
|
563
|
-
this.xhr = $.ajax({
|
|
564
|
-
url: url,
|
|
565
|
-
success: $.proxy(function (data, status, xhr) {
|
|
566
|
-
// 给包一层 <html/>,从而可以拿到完整的结构
|
|
567
|
-
var $doc = $('<html></html>');
|
|
568
|
-
$doc.append(data);
|
|
569
|
-
callback.success && callback.success.call(null, $doc, status, xhr);
|
|
570
|
-
}, this),
|
|
571
|
-
error: function error(xhr, status, err) {
|
|
572
|
-
callback.error && callback.error.call(null, xhr, status, err);
|
|
573
|
-
// Ajax失败时的回调处理
|
|
574
|
-
self.dispatch(EVENTS.pageLoadError);
|
|
575
|
-
},
|
|
576
|
-
complete: function complete(xhr, status) {
|
|
577
|
-
callback.complete && callback.complete.call(null, xhr, status);
|
|
578
|
-
self.dispatch(EVENTS.pageLoadComplete);
|
|
579
|
-
}
|
|
580
|
-
});
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* 对于 ajax 加载进来的页面,把其缓存起来
|
|
585
|
-
*
|
|
586
|
-
* @param {String} url url
|
|
587
|
-
* @param $doc ajax 载入的页面的 jq 对象,可以看做是该页面的 $(document)
|
|
588
|
-
* @private
|
|
589
|
-
*/
|
|
590
|
-
Router.prototype._parseDocument = function (url, $doc) {
|
|
591
|
-
var $innerView = $doc.find('.' + routerConfig.sectionGroupClass);
|
|
592
|
-
|
|
593
|
-
if (!$innerView.length) {
|
|
594
|
-
throw new Error('missing router view mark: ' + routerConfig.sectionGroupClass);
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
this._saveDocumentIntoCache($doc, url);
|
|
598
|
-
};
|
|
599
|
-
|
|
600
|
-
/**
|
|
601
|
-
* 把一个页面的相关信息保存到 this.cache 中
|
|
602
|
-
*
|
|
603
|
-
* 以页面的 baseUrl 为 key,而 value 则是一个 DocumentCache
|
|
604
|
-
*
|
|
605
|
-
* @param {*} doc doc
|
|
606
|
-
* @param {String} url url
|
|
607
|
-
* @private
|
|
608
|
-
*/
|
|
609
|
-
Router.prototype._saveDocumentIntoCache = function (doc, url) {
|
|
610
|
-
var urlAsKey = Util.toUrlObject(url).base;
|
|
611
|
-
var $doc = $(doc);
|
|
612
|
-
|
|
613
|
-
this.cache[urlAsKey] = {
|
|
614
|
-
$doc: $doc,
|
|
615
|
-
$content: $doc.find('.' + routerConfig.sectionGroupClass)
|
|
616
|
-
};
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
/**
|
|
620
|
-
* 从 sessionStorage 中获取保存下来的「当前状态」
|
|
621
|
-
*
|
|
622
|
-
* 如果解析失败,那么认为当前状态是 null
|
|
623
|
-
*
|
|
624
|
-
* @returns {State|null}
|
|
625
|
-
* @private
|
|
626
|
-
*/
|
|
627
|
-
Router.prototype._getLastState = function () {
|
|
628
|
-
var currentState = sessionStorage.getItem(this.sessionNames.currentState);
|
|
629
|
-
try {
|
|
630
|
-
currentState = JSON.parse(currentState);
|
|
631
|
-
} catch (e) {
|
|
632
|
-
currentState = null;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
return currentState;
|
|
636
|
-
};
|
|
637
|
-
|
|
638
|
-
/**
|
|
639
|
-
* 把一个状态设为当前状态,保存仅 sessionStorage 中
|
|
640
|
-
*
|
|
641
|
-
* @param {State} state
|
|
642
|
-
* @private
|
|
643
|
-
*/
|
|
644
|
-
Router.prototype._saveAsCurrentState = function (state) {
|
|
645
|
-
sessionStorage.setItem(this.sessionNames.currentState, JSON.stringify(state));
|
|
646
|
-
};
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* 获取下一个 state 的 id
|
|
650
|
-
*
|
|
651
|
-
* 读取 sessionStorage 里的最后的状态的 id,然后 + 1;如果原没设置,那么返回 1
|
|
652
|
-
*
|
|
653
|
-
* @returns {number}
|
|
654
|
-
* @private
|
|
655
|
-
*/
|
|
656
|
-
Router.prototype._getNextStateId = function () {
|
|
657
|
-
var maxStateId = sessionStorage.getItem(this.sessionNames.maxStateId);
|
|
658
|
-
return maxStateId ? parseInt(maxStateId, 10) + 1 : 1;
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* 把 sessionStorage 里的最后状态的 id 自加 1
|
|
663
|
-
*
|
|
664
|
-
* @private
|
|
665
|
-
*/
|
|
666
|
-
Router.prototype._incMaxStateId = function () {
|
|
667
|
-
sessionStorage.setItem(this.sessionNames.maxStateId, this._getNextStateId());
|
|
668
|
-
};
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* 从一个文档切换为显示另一个文档
|
|
672
|
-
*
|
|
673
|
-
* @param $from 目前显示的文档
|
|
674
|
-
* @param $to 待切换显示的新文档
|
|
675
|
-
* @param $visibleSection 新文档中展示的 section 元素
|
|
676
|
-
* @param direction 新文档切入方向
|
|
677
|
-
* @private
|
|
678
|
-
*/
|
|
679
|
-
Router.prototype._animateDocument = function ($from, $to, $visibleSection, direction) {
|
|
680
|
-
var sectionId = $visibleSection.attr('id');
|
|
681
|
-
|
|
682
|
-
var $visibleSectionInFrom = $from.find('.' + routerConfig.curPageClass);
|
|
683
|
-
$visibleSectionInFrom.addClass(routerConfig.visiblePageClass).removeClass(routerConfig.curPageClass);
|
|
684
|
-
|
|
685
|
-
$visibleSection.trigger(EVENTS.pageAnimationStart, [sectionId, $visibleSection]);
|
|
686
|
-
|
|
687
|
-
this._animateElement($from, $to, direction);
|
|
688
|
-
|
|
689
|
-
if ($.device.ie && Number($.device.ieVersion) <= 9) {
|
|
690
|
-
$visibleSectionInFrom.removeClass(routerConfig.visiblePageClass);
|
|
691
|
-
// 移除 document 前后,发送 beforePageRemove 和 pageRemoved 事件
|
|
692
|
-
$(window).trigger(EVENTS.beforePageRemove, [$from]);
|
|
693
|
-
$from.remove();
|
|
694
|
-
$(window).trigger(EVENTS.pageRemoved);
|
|
695
|
-
|
|
696
|
-
$visibleSection.trigger(EVENTS.pageAnimationEnd, [sectionId, $visibleSection]);
|
|
697
|
-
// 外层(init.js)中会绑定 pageInitInternal 事件,然后对页面进行初始化
|
|
698
|
-
$visibleSection.trigger(EVENTS.pageInit, [sectionId, $visibleSection]);
|
|
699
|
-
} else {
|
|
700
|
-
$from.animationEnd(function () {
|
|
701
|
-
$visibleSectionInFrom.removeClass(routerConfig.visiblePageClass);
|
|
702
|
-
// 移除 document 前后,发送 beforePageRemove 和 pageRemoved 事件
|
|
703
|
-
$(window).trigger(EVENTS.beforePageRemove, [$from]);
|
|
704
|
-
$from.remove();
|
|
705
|
-
$(window).trigger(EVENTS.pageRemoved);
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
$to.animationEnd(function () {
|
|
709
|
-
$visibleSection.trigger(EVENTS.pageAnimationEnd, [sectionId, $visibleSection]);
|
|
710
|
-
// 外层(init.js)中会绑定 pageInitInternal 事件,然后对页面进行初始化
|
|
711
|
-
$visibleSection.trigger(EVENTS.pageInit, [sectionId, $visibleSection]);
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
/**
|
|
717
|
-
* 把当前文档的展示 section 从一个 section 切换到另一个 section
|
|
718
|
-
*
|
|
719
|
-
* @param $from
|
|
720
|
-
* @param $to
|
|
721
|
-
* @param direction
|
|
722
|
-
* @private
|
|
723
|
-
*/
|
|
724
|
-
Router.prototype._animateSection = function ($from, $to, direction) {
|
|
725
|
-
var toId = $to.attr('id');
|
|
726
|
-
$from.isBack = direction === DIRECTION.rightToLeft ? false : true;
|
|
727
|
-
$from.trigger(EVENTS.beforePageSwitch, [$from.attr('id'), $from]);
|
|
728
|
-
|
|
729
|
-
// $from.removeClass(routerConfig.curPageClass);
|
|
730
|
-
$to.addClass(routerConfig.curPageClass).addClass("page-transiting");
|
|
731
|
-
$to.isBack = direction === DIRECTION.rightToLeft ? false : true;
|
|
732
|
-
|
|
733
|
-
// 给容器添加scroller自由滚动特性
|
|
734
|
-
// 解决virtual-dom和js-scroller公用冲突的bug,全部使用原生scroller
|
|
735
|
-
$('[data-toggle="scroller"]').not(".native-scroll").not(".javascript-scroll").scroller({
|
|
736
|
-
type: 'native'
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
$to.trigger(EVENTS.pageAnimationStart, [toId, $to]);
|
|
740
|
-
this._animateElement($from, $to, direction);
|
|
741
|
-
// 判断是否PageInit
|
|
742
|
-
var _isInit = true;
|
|
743
|
-
for (var key in this.hash2ViewId) {
|
|
744
|
-
if (this.hash2ViewId[key] === toId) {
|
|
745
|
-
_isInit = false;
|
|
746
|
-
break;
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
// IE9 及以下不支持 动画事件
|
|
751
|
-
if ($.device.ie && Number($.device.ieVersion) <= 9) {
|
|
752
|
-
$from.removeClass(routerConfig.curPageClass);
|
|
753
|
-
$to.removeClass("page-transiting");
|
|
754
|
-
$to.trigger(EVENTS.pageAnimationEnd, [toId, $to]);
|
|
755
|
-
// 外层(init.js)中会绑定 pageInitInternal 事件,然后对页面进行初始化
|
|
756
|
-
if (_isInit) {
|
|
757
|
-
$to.trigger(EVENTS.pageInit, [toId, $to]);
|
|
758
|
-
}
|
|
759
|
-
} else {
|
|
760
|
-
$to.animationEnd(function () {
|
|
761
|
-
$from.removeClass(routerConfig.curPageClass);
|
|
762
|
-
$to.removeClass("page-transiting");
|
|
763
|
-
$to.trigger(EVENTS.pageAnimationEnd, [toId, $to]);
|
|
764
|
-
// 外层(init.js)中会绑定 pageInitInternal 事件,然后对页面进行初始化
|
|
765
|
-
if (_isInit) {
|
|
766
|
-
$to.trigger(EVENTS.pageInit, [toId, $to]);
|
|
767
|
-
}
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
/**
|
|
773
|
-
* 切换显示两个元素
|
|
774
|
-
*
|
|
775
|
-
* 切换是通过更新 class 来实现的,而具体的切换动画则是 class 关联的 css 来实现
|
|
776
|
-
*
|
|
777
|
-
* @param $from 当前显示的元素
|
|
778
|
-
* @param $to 待显示的元素
|
|
779
|
-
* @param direction 切换的方向
|
|
780
|
-
* @private
|
|
781
|
-
*/
|
|
782
|
-
Router.prototype._animateElement = function ($from, $to, direction) {
|
|
783
|
-
// todo: 可考虑如果入参不指定,那么尝试读取 $to 的属性,再没有再使用默认的
|
|
784
|
-
// 考虑读取点击的链接上指定的方向
|
|
785
|
-
if (typeof direction === 'undefined') {
|
|
786
|
-
direction = DIRECTION.rightToLeft;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
var animPageClasses = ['page-from-center-to-left', 'page-from-center-to-right', 'page-from-right-to-center', 'page-from-right-to-center-compatible', 'page-from-left-to-center'].join(' ');
|
|
790
|
-
|
|
791
|
-
var classForFrom, classForTo;
|
|
792
|
-
switch (direction) {
|
|
793
|
-
case DIRECTION.rightToLeft:
|
|
794
|
-
classForFrom = 'page-from-center-to-left';
|
|
795
|
-
//classForTo = $.device.ios ? 'page-from-right-to-center-compatible' : 'page-from-right-to-center';
|
|
796
|
-
classForTo = $.device.ios && Version._compareVersion($.device.osVersion, '10.0.0') >= 0 && Version._compareVersion($.device.osVersion, '11.0.0') < 0 ? 'page-from-right-to-center-compatible' : 'page-from-right-to-center';
|
|
797
|
-
break;
|
|
798
|
-
case DIRECTION.leftToRight:
|
|
799
|
-
classForFrom = 'page-from-center-to-right';
|
|
800
|
-
classForTo = 'page-from-left-to-center';
|
|
801
|
-
break;
|
|
802
|
-
default:
|
|
803
|
-
classForFrom = 'page-from-center-to-left';
|
|
804
|
-
//classForTo = $.device.ios ? 'page-from-right-to-center-compatible' : 'page-from-right-to-center';
|
|
805
|
-
classForTo = $.device.ios && Version._compareVersion($.device.osVersion, '10.0.0') >= 0 && Version._compareVersion($.device.osVersion, '11.0.0') < 0 ? 'page-from-right-to-center-compatible' : 'page-from-right-to-center';
|
|
806
|
-
break;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
$from.removeClass(animPageClasses).addClass(classForFrom);
|
|
810
|
-
$to.removeClass(animPageClasses).addClass(classForTo);
|
|
811
|
-
|
|
812
|
-
// ie 9及以下不支持动画事件
|
|
813
|
-
if ($.device.ie && Number($.device.ieVersion) <= 9) {
|
|
814
|
-
$from.removeClass(animPageClasses);
|
|
815
|
-
$to.removeClass(animPageClasses);
|
|
816
|
-
} else {
|
|
817
|
-
$from.animationEnd(function () {
|
|
818
|
-
$from.removeClass(animPageClasses);
|
|
819
|
-
});
|
|
820
|
-
$to.animationEnd(function () {
|
|
821
|
-
$to.removeClass(animPageClasses);
|
|
822
|
-
});
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* 获取当前显示的第一个 section
|
|
828
|
-
*
|
|
829
|
-
* @returns {*}
|
|
830
|
-
* @private
|
|
831
|
-
*/
|
|
832
|
-
Router.prototype._getCurrentSection = function () {
|
|
833
|
-
return this.$view.find('.' + routerConfig.curPageClass).eq(0);
|
|
834
|
-
};
|
|
835
|
-
|
|
836
|
-
/**
|
|
837
|
-
* popState 事件关联着的后退处理
|
|
838
|
-
*
|
|
839
|
-
* 判断两个 state 判断是否是属于同一个文档,然后做对应的 section 或文档切换;
|
|
840
|
-
* 同时在切换后把新 state 设为当前 state
|
|
841
|
-
*
|
|
842
|
-
* @param {State} state 新 state
|
|
843
|
-
* @param {State} fromState 旧 state
|
|
844
|
-
* @private
|
|
845
|
-
*/
|
|
846
|
-
Router.prototype._back = function (state, fromState) {
|
|
847
|
-
// if (this._isTheSameDocument(state.url.full, fromState.url.full)) {
|
|
848
|
-
// var $newPage = $('#' + state.pageId);
|
|
849
|
-
// if ($newPage.length) {
|
|
850
|
-
// var $currentPage = this._getCurrentSection();
|
|
851
|
-
// this._animateSection($currentPage, $newPage, DIRECTION.leftToRight);
|
|
852
|
-
// this._saveAsCurrentState(state);
|
|
853
|
-
// } else {
|
|
854
|
-
// // location.href = state.url.full;
|
|
855
|
-
// location.href = state.url.base
|
|
856
|
-
// }
|
|
857
|
-
// } else {
|
|
858
|
-
// this._saveDocumentIntoCache($(document), fromState.url.full);
|
|
859
|
-
// this._switchToDocument(state.url.full, false, false, DIRECTION.leftToRight);
|
|
860
|
-
// this._saveAsCurrentState(state);
|
|
861
|
-
// }
|
|
862
|
-
var $newPage = $('#' + state.pageId);
|
|
863
|
-
if ($newPage.length) {
|
|
864
|
-
var $currentPage = this._getCurrentSection();
|
|
865
|
-
this._animateSection($currentPage, $newPage, DIRECTION.leftToRight);
|
|
866
|
-
this._saveAsCurrentState(state);
|
|
867
|
-
} else {
|
|
868
|
-
location.href = state.url.full;
|
|
869
|
-
//location.href = state.url.base
|
|
870
|
-
}
|
|
871
|
-
};
|
|
872
|
-
|
|
873
|
-
/**
|
|
874
|
-
* popState 事件关联着的前进处理,类似于 _back,不同的是切换方向
|
|
875
|
-
*
|
|
876
|
-
* @param {State} state 新 state
|
|
877
|
-
* @param {State} fromState 旧 state
|
|
878
|
-
* @private
|
|
879
|
-
*/
|
|
880
|
-
Router.prototype._forward = function (state, fromState) {
|
|
881
|
-
if (this._isTheSameDocument(state.url.full, fromState.url.full)) {
|
|
882
|
-
var $newPage = $('#' + state.pageId);
|
|
883
|
-
if ($newPage.length) {
|
|
884
|
-
var $currentPage = this._getCurrentSection();
|
|
885
|
-
this._animateSection($currentPage, $newPage, DIRECTION.rightToLeft);
|
|
886
|
-
this._saveAsCurrentState(state);
|
|
887
|
-
} else {
|
|
888
|
-
// location.href = state.url.full;
|
|
889
|
-
location.href = state.url.base;
|
|
890
|
-
}
|
|
891
|
-
} else {
|
|
892
|
-
this._saveDocumentIntoCache($(document), fromState.url.full);
|
|
893
|
-
this._switchToDocument(state.url.full, false, false, DIRECTION.rightToLeft);
|
|
894
|
-
this._saveAsCurrentState(state);
|
|
895
|
-
}
|
|
896
|
-
};
|
|
897
|
-
|
|
898
|
-
/**
|
|
899
|
-
* popState 事件处理
|
|
900
|
-
*
|
|
901
|
-
* 根据 pop 出来的 state 和当前 state 来判断是前进还是后退
|
|
902
|
-
*
|
|
903
|
-
* @param event popstate事件对象
|
|
904
|
-
* @param routerMatch 路由规则,支持通配符
|
|
905
|
-
* @private
|
|
906
|
-
*/
|
|
907
|
-
Router.prototype._onPopState = function (event, routerMatch) {
|
|
908
|
-
var state = event.state;
|
|
909
|
-
// if not a valid state, do nothing
|
|
910
|
-
if (!state || !state.pageId) {
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
var lastState = this._getLastState();
|
|
915
|
-
|
|
916
|
-
if (!lastState) {
|
|
917
|
-
console.error && console.error('Missing last state when backward or forward');
|
|
918
|
-
return;
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
if (state.id === lastState.id) {
|
|
922
|
-
return;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
if (state.id < lastState.id) {
|
|
926
|
-
this._back(state, lastState);
|
|
927
|
-
} else {
|
|
928
|
-
this._forward(state, lastState);
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
// 前进后退都记录当前的hash对应的viewId,用于v-dom查找对应hash的node对象(已修复)
|
|
932
|
-
this.hash2ViewId[routerMatch] = state.pageId;
|
|
933
|
-
|
|
934
|
-
// 更新当前可见页面的node
|
|
935
|
-
// $.setNode(this.vdoms[lastState.url.fragment])
|
|
936
|
-
//$.setNode(this.vdoms[Util.getUrlFragment(location.href)])
|
|
937
|
-
};
|
|
938
|
-
|
|
939
|
-
/**
|
|
940
|
-
* 页面进入到一个新状态
|
|
941
|
-
*
|
|
942
|
-
* 把新状态 push 进去,设置为当前的状态,然后把 maxState 的 id +1。
|
|
943
|
-
*
|
|
944
|
-
* @param {String} url 新状态的 url
|
|
945
|
-
* @param {String} sectionId 新状态中显示的 section 元素的 id
|
|
946
|
-
* @private
|
|
947
|
-
*/
|
|
948
|
-
Router.prototype._pushNewState = function (url, sectionId) {
|
|
949
|
-
var state = {
|
|
950
|
-
id: this._getNextStateId(),
|
|
951
|
-
pageId: sectionId,
|
|
952
|
-
url: Util.toUrlObject(url)
|
|
953
|
-
};
|
|
954
|
-
// 存一个标识 让不兼容 history 的 stateChange方法 不会再 pushState 后执行
|
|
955
|
-
window.__isPushState = true;
|
|
956
|
-
// 不兼容history 的 url(也就是第三个参数) 中不能含有 原来的 # 字符
|
|
957
|
-
url = $.device.hasNativeHistory ? url : url.slice(1);
|
|
958
|
-
theHistory.pushState(state, '', url);
|
|
959
|
-
this._saveAsCurrentState(state);
|
|
960
|
-
this._incMaxStateId();
|
|
961
|
-
};
|
|
962
|
-
|
|
963
|
-
/**
|
|
964
|
-
* 生成一个随机的 id
|
|
965
|
-
*
|
|
966
|
-
* @returns {string}
|
|
967
|
-
* @private
|
|
968
|
-
*/
|
|
969
|
-
Router.prototype._generateRandomId = function () {
|
|
970
|
-
return "page-" + +new Date();
|
|
971
|
-
};
|
|
972
|
-
|
|
973
|
-
Router.prototype.dispatch = function (event) {
|
|
974
|
-
var e = new CustomEvent(event, {
|
|
975
|
-
bubbles: true,
|
|
976
|
-
cancelable: true
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
//noinspection JSUnresolvedFunction
|
|
980
|
-
window.dispatchEvent(e);
|
|
981
|
-
};
|
|
982
|
-
|
|
983
|
-
exports.Router = Router;
|
|
984
|
-
exports.Util = Util;
|
|
985
|
-
exports.routerConfig = routerConfig;
|
|
986
|
-
exports.EVENTS = EVENTS;
|
|
987
|
-
|
|
988
|
-
// /**
|
|
989
|
-
// * 判断一个链接是否使用 router 来处理
|
|
990
|
-
// *
|
|
991
|
-
// * @param $link
|
|
992
|
-
// * @returns {boolean}
|
|
993
|
-
// */
|
|
994
|
-
// function isInRouterBlackList($link) {
|
|
995
|
-
// var classBlackList = [
|
|
996
|
-
// 'external',
|
|
997
|
-
// 'tab-link',
|
|
998
|
-
// 'open-popup',
|
|
999
|
-
// 'close-popup',
|
|
1000
|
-
// 'open-panel',
|
|
1001
|
-
// 'close-panel'
|
|
1002
|
-
// ];
|
|
1003
|
-
//
|
|
1004
|
-
// for (var i = classBlackList.length -1 ; i >= 0; i--) {
|
|
1005
|
-
// if ($link.hasClass(classBlackList[i])) {
|
|
1006
|
-
// return true;
|
|
1007
|
-
// }
|
|
1008
|
-
// }
|
|
1009
|
-
//
|
|
1010
|
-
// var linkEle = $link.get(0);
|
|
1011
|
-
// var linkHref = linkEle.getAttribute('href');
|
|
1012
|
-
//
|
|
1013
|
-
// var protoWhiteList = [
|
|
1014
|
-
// 'http',
|
|
1015
|
-
// 'https'
|
|
1016
|
-
// ];
|
|
1017
|
-
//
|
|
1018
|
-
// //如果非noscheme形式的链接,且协议不是http(s),那么路由不会处理这类链接
|
|
1019
|
-
// if (/^(\w+):/.test(linkHref) && protoWhiteList.indexOf(RegExp.$1) < 0) {
|
|
1020
|
-
// return true;
|
|
1021
|
-
// }
|
|
1022
|
-
//
|
|
1023
|
-
// //noinspection RedundantIfStatementJS
|
|
1024
|
-
// if (linkEle.hasAttribute('external')) {
|
|
1025
|
-
// return true;
|
|
1026
|
-
// }
|
|
1027
|
-
//
|
|
1028
|
-
// return false;
|
|
1029
|
-
// }
|
|
1030
|
-
|
|
1031
|
-
// /**
|
|
1032
|
-
// * 自定义是否执行路由功能的过滤器
|
|
1033
|
-
// *
|
|
1034
|
-
// * 可以在外部定义 $.config.routerFilter 函数,实参是点击链接的 Zepto 对象。
|
|
1035
|
-
// *
|
|
1036
|
-
// * @param $link 当前点击的链接的 Zepto 对象
|
|
1037
|
-
// * @returns {boolean} 返回 true 表示执行路由功能,否则不做路由处理
|
|
1038
|
-
// */
|
|
1039
|
-
// function customClickFilter($link) {
|
|
1040
|
-
// // 路由功能开关过滤器,返回 false 表示当前点击链接不使用路由
|
|
1041
|
-
// var customRouterFilter = $link => {
|
|
1042
|
-
// // 某个区域的 a 链接不想使用路由功能
|
|
1043
|
-
// if ($link.is('.disable-router a')) {
|
|
1044
|
-
// return false;
|
|
1045
|
-
// }
|
|
1046
|
-
//
|
|
1047
|
-
// return true;
|
|
1048
|
-
// };
|
|
1049
|
-
// if ($.isFunction(customRouterFilter)) {
|
|
1050
|
-
// var filterResult = customRouterFilter($link);
|
|
1051
|
-
// if (typeof filterResult === 'boolean') {
|
|
1052
|
-
// return filterResult;
|
|
1053
|
-
// }
|
|
1054
|
-
// }
|
|
1055
|
-
//
|
|
1056
|
-
// return true;
|
|
1057
|
-
// }
|
|
1058
|
-
|
|
1059
|
-
// $(function() {
|
|
1060
|
-
// // 当前浏览器是否支持sessionStorage特性
|
|
1061
|
-
// if (!Util.supportStorage()) {
|
|
1062
|
-
// return;
|
|
1063
|
-
// }
|
|
1064
|
-
//
|
|
1065
|
-
// // 页面元素需要定义.page,不然路由模块默认不会生效
|
|
1066
|
-
// var $pages = $('.' + routerConfig.pageClass);
|
|
1067
|
-
// if (!$pages.length) {
|
|
1068
|
-
// var warnMsg = 'Disable router function because of no .page elements';
|
|
1069
|
-
// if (window.console && window.console.warn) {
|
|
1070
|
-
// console.warn(warnMsg);
|
|
1071
|
-
// }
|
|
1072
|
-
// return;
|
|
1073
|
-
// }
|
|
1074
|
-
//
|
|
1075
|
-
// // 初始化路由:historyState
|
|
1076
|
-
// var router = $.router = new Router();
|
|
1077
|
-
//
|
|
1078
|
-
// // 为page容器中的a标签注册点击事件
|
|
1079
|
-
// $(document).on('click', 'a', function(e) {
|
|
1080
|
-
// var $target = $(e.currentTarget);
|
|
1081
|
-
//
|
|
1082
|
-
// var filterResult = customClickFilter($target);
|
|
1083
|
-
// if (!filterResult) {
|
|
1084
|
-
// return;
|
|
1085
|
-
// }
|
|
1086
|
-
//
|
|
1087
|
-
// if (isInRouterBlackList($target)) {
|
|
1088
|
-
// return;
|
|
1089
|
-
// }
|
|
1090
|
-
//
|
|
1091
|
-
// e.preventDefault();
|
|
1092
|
-
//
|
|
1093
|
-
// if ($target.hasClass('back')) {
|
|
1094
|
-
// router.back();
|
|
1095
|
-
// } else {
|
|
1096
|
-
// var url = $target.attr('href');
|
|
1097
|
-
// if (!url || url === '#') {
|
|
1098
|
-
// return;
|
|
1099
|
-
// }
|
|
1100
|
-
//
|
|
1101
|
-
// var ignoreCache = $target.attr('data-no-cache') === 'true';
|
|
1102
|
-
//
|
|
1103
|
-
// router.load(url, ignoreCache);
|
|
1104
|
-
// }
|
|
1105
|
-
// });
|
|
1106
|
-
// });
|
|
1107
|
-
|
|
1108
|
-
/***/ }),
|
|
1109
|
-
|
|
1110
|
-
/***/ 58:
|
|
1111
|
-
/***/ (function(module, exports, __webpack_require__) {
|
|
1112
|
-
|
|
1113
|
-
"use strict";
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
Object.defineProperty(exports, "__esModule", {
|
|
1117
|
-
value: true
|
|
1118
|
-
});
|
|
1119
|
-
/**
|
|
1120
|
-
* Created by dfzq on 2017/7/31.
|
|
1121
|
-
*/
|
|
1122
|
-
|
|
1123
|
-
/**
|
|
1124
|
-
* 末尾补.0
|
|
1125
|
-
* @param num 原始值
|
|
1126
|
-
* @param n 位数最大的值
|
|
1127
|
-
* @returns {*}
|
|
1128
|
-
*/
|
|
1129
|
-
var padZero = function padZero(num, n) {
|
|
1130
|
-
var len = num.split('.').length;
|
|
1131
|
-
while (len < n) {
|
|
1132
|
-
num = num + '.0';
|
|
1133
|
-
len++;
|
|
1134
|
-
}
|
|
1135
|
-
return num;
|
|
1136
|
-
};
|
|
1137
|
-
|
|
1138
|
-
/**
|
|
1139
|
-
* 获取APP版本号
|
|
1140
|
-
* @param _
|
|
1141
|
-
* @returns {*}
|
|
1142
|
-
*/
|
|
1143
|
-
var getVersion = function getVersion(_) {
|
|
1144
|
-
var groups = navigator.userAgent.toLowerCase().match(/DFYJ\/([\d.]+)/i);
|
|
1145
|
-
if (!groups) {
|
|
1146
|
-
return undefined;
|
|
1147
|
-
} else {
|
|
1148
|
-
return groups[1];
|
|
1149
|
-
}
|
|
1150
|
-
};
|
|
1151
|
-
|
|
1152
|
-
/**
|
|
1153
|
-
* 比较手机系统版本,arg1 > arg2, return 1; arg1 == arg2, return 0; arg1 < arg2, return -1
|
|
1154
|
-
* @param compareVersion
|
|
1155
|
-
* @returns {number}
|
|
1156
|
-
*/
|
|
1157
|
-
var _compareVersion = function _compareVersion(a, b) {
|
|
1158
|
-
// 补.0操作
|
|
1159
|
-
var _as = a.split('.');
|
|
1160
|
-
var _bs = b.split('.');
|
|
1161
|
-
var max = Math.max(_as.length, _bs.length);
|
|
1162
|
-
a = padZero(a, max);
|
|
1163
|
-
b = padZero(b, max);
|
|
1164
|
-
|
|
1165
|
-
var as = a.split('.');
|
|
1166
|
-
var bs = b.split('.');
|
|
1167
|
-
if (a === b) return 0;
|
|
1168
|
-
|
|
1169
|
-
for (var i = 0; i < as.length; i++) {
|
|
1170
|
-
var x = parseInt(as[i]);
|
|
1171
|
-
if (!bs[i]) return 1;
|
|
1172
|
-
var y = parseInt(bs[i]);
|
|
1173
|
-
if (x < y) return -1;
|
|
1174
|
-
if (x > y) return 1;
|
|
1175
|
-
}
|
|
1176
|
-
return -1;
|
|
1177
|
-
};
|
|
1178
|
-
|
|
1179
|
-
/**
|
|
1180
|
-
* 比较APP版本,比compareVersion大则返回1,否则返回-1;相等返回0;
|
|
1181
|
-
* @param compareVersion
|
|
1182
|
-
* @returns {number}
|
|
1183
|
-
*/
|
|
1184
|
-
var compareVersion = function compareVersion(_compareVersion2) {
|
|
1185
|
-
// 获取当前版本号
|
|
1186
|
-
var currentVersion = getVersion();
|
|
1187
|
-
if (!currentVersion) {
|
|
1188
|
-
return 1;
|
|
1189
|
-
} else {
|
|
1190
|
-
return _compareVersion(currentVersion, _compareVersion2);
|
|
1191
|
-
}
|
|
1192
|
-
};
|
|
1193
|
-
|
|
1194
|
-
exports.getVersion = getVersion;
|
|
1195
|
-
exports.compareVersion = compareVersion;
|
|
1196
|
-
exports._compareVersion = _compareVersion;
|
|
1197
|
-
|
|
1198
|
-
/***/ })
|
|
1199
|
-
|
|
1200
|
-
},[235]);
|
|
1201
|
-
});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.fastman=t():e.fastman=t()}(this,function(){return webpackJsonpfastman([7],{150:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=t.getUrlFragment=function(e){var t=e.indexOf("#");return-1===t?"/":e.slice(t+1)},i=t.getAbsoluteUrl=function(e){var t=document.createElement("a");t.setAttribute("href",e);var a=t.href;return t=null,a},o=t.getBaseUrl=function(e){var t=e.indexOf("#");return-1===t?e.slice(0):e.slice(0,t)};t.toUrlObject=function(e){var t=i(e);return{base:o(t),full:t,original:e,fragment:r(e)}},t.supportStorage=function(){var e="ob.router.storage.ability";try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(e){return!1}}},235:function(e,t,a){e.exports=a(52)},52:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=a(150),i=a(58);window.CustomEvent||(window.CustomEvent=function(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var a=document.createEvent("CustomEvent");return a.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),a},window.CustomEvent.prototype=window.Event.prototype);var o={pageLoadStart:"pageLoadStart",pageLoadCancel:"pageLoadCancel",pageLoadError:"pageLoadError",pageLoadComplete:"pageLoadComplete",pageAnimationStart:"pageAnimationStart",pageAnimationEnd:"pageAnimationEnd",beforePageRemove:"beforePageRemove",pageRemoved:"pageRemoved",beforePageSwitch:"beforePageSwitch",pageInit:"pageInitInternal"},n={sectionGroupClass:"page-group",curPageClass:"page-current",visiblePageClass:"page-visible",pageClass:"page"},s={leftToRight:"from-left-to-right",rightToLeft:"from-right-to-left"},c=$.device.hasNativeHistory?window.history:History,l=function(e){for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))return!1;return!0},u=function(){if($.device.hasNativeHistory)return c.state;var e=c.getState().data;return l(e)?null:e},g=function(){this.sessionNames={currentState:"application.router.currentState",maxStateId:"application.router.maxStateId"},this._init(),this.xhr=null,this.vdoms={},this.hash2ViewId={},this.popstateFlag=!1};g.prototype._init=function(){this.$view=$("body"),this.cache={};var e=$(document),t=location.href;this._saveDocumentIntoCache(e,t);var a,i=(r.toUrlObject(t),e.find("."+n.pageClass)),o=e.find("."+n.curPageClass),s=o.eq(0);if(o.length||(o=i.eq(0)),o.attr("id")||o.attr("id",null==u()?this._generateRandomId():u().pageId),s.length&&s.attr("id")!==o.attr("id")?(s.removeClass(n.curPageClass),o.addClass(n.curPageClass)):o.addClass(n.curPageClass),a=o.attr("id"),null===u()){var l={id:this._getNextStateId(),url:r.toUrlObject(t),pageId:a},g=t;if($.device.hasNativeHistory||(g=l.url.fragment,window.__isReplaceState=!0),!$.device.hasNativeHistory&&/\?&_suid=.+$/.test(t))return;c.replaceState(l,"",g),this._saveAsCurrentState(l),this._incMaxStateId()}},g.prototype.load=function(e,t){this._switchToSection(e)},g.prototype.forward=function(){c.forward()},g.prototype.back=function(){c.back()},g.prototype.loadPage=g.prototype.load,g.prototype._switchToSection=function(e){var t=e.path,a=e.match;if(t){var r,i=this._getCurrentSection();if(r=this.hash2ViewId[a]?$("#"+this.hash2ViewId[a]):this.$view.find("."+n.pageClass).eq(-1),i!==r){this._animateSection(i,r,s.rightToLeft);var o;r.attr("id")?o=r.attr("id"):(o=this._generateRandomId(),r.attr("id",o)),this.hash2ViewId[a]=o,this._pushNewState("#"+t,o)}}},g.prototype._switchToDocument=function(e,t,a,i){var o=r.toUrlObject(e).base;t&&delete this.cache[o];var n=this.cache[o],s=this;n?this._doSwitchDocument(e,a,i):this._loadDocument(e,{success:function(t){try{s._parseDocument(e,t),s._doSwitchDocument(e,a,i)}catch(t){location.href=e}},error:function(){location.href=e}})},g.prototype._doSwitchDocument=function(e,t,a){void 0===t&&(t=!0);var i,s=r.toUrlObject(e),c=this.$view.find("."+n.sectionGroupClass),l=$($("<div></div>").append(this.cache[s.base].$content).html()),u=l.find("."+n.pageClass),g=l.find("."+n.curPageClass);s.fragment&&(i=l.find("#"+s.fragment)),i&&i.length?g=i.eq(0):g.length||(g=u.eq(0)),g.attr("id")||g.attr("id",this._generateRandomId());var p=this._getCurrentSection();p.trigger(o.beforePageSwitch,[p.attr("id"),p]),u.removeClass(n.curPageClass),g.addClass(n.curPageClass),this.$view.prepend(l),this._animateDocument(c,l,g,a),t&&this._pushNewState(e,g.attr("id"))},g.prototype._isTheSameDocument=function(e,t){return r.toUrlObject(e).base===r.toUrlObject(t).base},g.prototype._loadDocument=function(e,t){this.xhr&&this.xhr.readyState<4&&(this.xhr.onreadystatechange=function(){},this.xhr.abort(),this.dispatch(o.pageLoadCancel)),this.dispatch(o.pageLoadStart),t=t||{};var a=this;this.xhr=$.ajax({url:e,success:$.proxy(function(e,a,r){var i=$("<html></html>");i.append(e),t.success&&t.success.call(null,i,a,r)},this),error:function(e,r,i){t.error&&t.error.call(null,e,r,i),a.dispatch(o.pageLoadError)},complete:function(e,r){t.complete&&t.complete.call(null,e,r),a.dispatch(o.pageLoadComplete)}})},g.prototype._parseDocument=function(e,t){if(!t.find("."+n.sectionGroupClass).length)throw new Error("missing router view mark: "+n.sectionGroupClass);this._saveDocumentIntoCache(t,e)},g.prototype._saveDocumentIntoCache=function(e,t){var a=r.toUrlObject(t).base,i=$(e);this.cache[a]={$doc:i,$content:i.find("."+n.sectionGroupClass)}},g.prototype._getLastState=function(){var e=sessionStorage.getItem(this.sessionNames.currentState);try{e=JSON.parse(e)}catch(t){e=null}return e},g.prototype._saveAsCurrentState=function(e){sessionStorage.setItem(this.sessionNames.currentState,JSON.stringify(e))},g.prototype._getNextStateId=function(){var e=sessionStorage.getItem(this.sessionNames.maxStateId);return e?parseInt(e,10)+1:1},g.prototype._incMaxStateId=function(){sessionStorage.setItem(this.sessionNames.maxStateId,this._getNextStateId())},g.prototype._animateDocument=function(e,t,a,r){var i=a.attr("id"),s=e.find("."+n.curPageClass);s.addClass(n.visiblePageClass).removeClass(n.curPageClass),a.trigger(o.pageAnimationStart,[i,a]),this._animateElement(e,t,r),$.device.ie&&Number($.device.ieVersion)<=9?(s.removeClass(n.visiblePageClass),$(window).trigger(o.beforePageRemove,[e]),e.remove(),$(window).trigger(o.pageRemoved),a.trigger(o.pageAnimationEnd,[i,a]),a.trigger(o.pageInit,[i,a])):(e.animationEnd(function(){s.removeClass(n.visiblePageClass),$(window).trigger(o.beforePageRemove,[e]),e.remove(),$(window).trigger(o.pageRemoved)}),t.animationEnd(function(){a.trigger(o.pageAnimationEnd,[i,a]),a.trigger(o.pageInit,[i,a])}))},g.prototype._animateSection=function(e,t,a){var r=t.attr("id");e.isBack=a!==s.rightToLeft,e.trigger(o.beforePageSwitch,[e.attr("id"),e]),t.addClass(n.curPageClass).addClass("page-transiting"),t.isBack=a!==s.rightToLeft,$('[data-toggle="scroller"]').not(".native-scroll").not(".javascript-scroll").scroller({type:"native"}),t.trigger(o.pageAnimationStart,[r,t]),this._animateElement(e,t,a);var i=!0;for(var c in this.hash2ViewId)if(this.hash2ViewId[c]===r){i=!1;break}$.device.ie&&Number($.device.ieVersion)<=9?(e.removeClass(n.curPageClass),t.removeClass("page-transiting"),t.trigger(o.pageAnimationEnd,[r,t]),i&&t.trigger(o.pageInit,[r,t])):t.animationEnd(function(){e.removeClass(n.curPageClass),t.removeClass("page-transiting"),t.trigger(o.pageAnimationEnd,[r,t]),i&&t.trigger(o.pageInit,[r,t])})},g.prototype._animateElement=function(e,t,a){void 0===a&&(a=s.rightToLeft);var r,o,n=["page-from-center-to-left","page-from-center-to-right","page-from-right-to-center","page-from-right-to-center-compatible","page-from-left-to-center"].join(" ");switch(a){case s.rightToLeft:r="page-from-center-to-left",o=$.device.ios&&i._compareVersion($.device.osVersion,"10.0.0")>=0&&i._compareVersion($.device.osVersion,"11.0.0")<0?"page-from-right-to-center-compatible":"page-from-right-to-center";break;case s.leftToRight:r="page-from-center-to-right",o="page-from-left-to-center";break;default:r="page-from-center-to-left",o=$.device.ios&&i._compareVersion($.device.osVersion,"10.0.0")>=0&&i._compareVersion($.device.osVersion,"11.0.0")<0?"page-from-right-to-center-compatible":"page-from-right-to-center"}e.removeClass(n).addClass(r),t.removeClass(n).addClass(o),$.device.ie&&Number($.device.ieVersion)<=9?(e.removeClass(n),t.removeClass(n)):(e.animationEnd(function(){e.removeClass(n)}),t.animationEnd(function(){t.removeClass(n)}))},g.prototype._getCurrentSection=function(){return this.$view.find("."+n.curPageClass).eq(0)},g.prototype._back=function(e,t){var a=$("#"+e.pageId);if(a.length){var r=this._getCurrentSection();this._animateSection(r,a,s.leftToRight),this._saveAsCurrentState(e)}else location.href=e.url.full},g.prototype._forward=function(e,t){if(this._isTheSameDocument(e.url.full,t.url.full)){var a=$("#"+e.pageId);if(a.length){var r=this._getCurrentSection();this._animateSection(r,a,s.rightToLeft),this._saveAsCurrentState(e)}else location.href=e.url.base}else this._saveDocumentIntoCache($(document),t.url.full),this._switchToDocument(e.url.full,!1,!1,s.rightToLeft),this._saveAsCurrentState(e)},g.prototype._onPopState=function(e,t){var a=e.state;if(a&&a.pageId){var r=this._getLastState();if(!r)return void console.error;a.id!==r.id&&(a.id<r.id?this._back(a,r):this._forward(a,r),this.hash2ViewId[t]=a.pageId)}},g.prototype._pushNewState=function(e,t){var a={id:this._getNextStateId(),pageId:t,url:r.toUrlObject(e)};window.__isPushState=!0,e=$.device.hasNativeHistory?e:e.slice(1),c.pushState(a,"",e),this._saveAsCurrentState(a),this._incMaxStateId()},g.prototype._generateRandomId=function(){return"page-"+ +new Date},g.prototype.dispatch=function(e){var t=new CustomEvent(e,{bubbles:!0,cancelable:!0});window.dispatchEvent(t)},t.Router=g,t.Util=r,t.routerConfig=n,t.EVENTS=o},58:function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(e,t){for(var a=e.split(".").length;a<t;)e+=".0",a++;return e},i=function(e){var t=navigator.userAgent.toLowerCase().match(/DFYJ\/([\d.]+)/i);return t?t[1]:void 0},o=function(e,t){var a=e.split("."),i=t.split("."),o=Math.max(a.length,i.length);e=r(e,o),t=r(t,o);var n=e.split("."),s=t.split(".");if(e===t)return 0;for(var c=0;c<n.length;c++){var l=parseInt(n[c]);if(!s[c])return 1;var u=parseInt(s[c]);if(l<u)return-1;if(l>u)return 1}return-1},n=function(e){var t=i();return t?o(t,e):1};t.getVersion=i,t.compareVersion=n,t._compareVersion=o}},[235])});
|