-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathminirouter.js
96 lines (74 loc) · 2.56 KB
/
minirouter.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
/*
var mockController = {
render: function(){
return "<div></div>"
}
onEnter: function(){
//this对象为当前组件,即{path, controller: controller}对象
}
onLeave: function(){
}
}
*/
(function (window) {
function getRoute(routerObj, path, defaultPath) {
var key = (path.hash || '#/').slice(1).split('?')[0];
if (routerObj.hasOwnProperty(key)) {
return routerObj[key];
}
if (path !== defaultPath && !!defaultPath) {
return getRoute(routerObj, defaultPath);
}
}
function getFullPath(path) {
if (URL.prototype.isPrototypeOf(path)) return path;
var link = document.createElement('a');
link.setAttribute('href', path);
return new URL(link.href);
}
function noop() {
}
var Router = function Router(container) {
this._container = typeof container === 'string' ? document.querySelector(container) : container;
this._routes = {};
};
Router.prototype.use = function use(path, controller) {
if (typeof (controller.render) !== 'function') {
throw new Error('未实现render');
}
var map = this._routes || {};
map[path] = {
path: path,
controller: controller
}
return this;
}
Router.prototype.default = function (defaultPath) {
this._defaultPath = defaultPath;
return this;
}
Router.prototype.go = function (nextPath, prev, replace) {
var current = getRoute(this._routes, prev || window.location),
next = getRoute(this._routes, nextPath, this._defaultPath);
current && !!prev && (current.controller.onLeave || noop).call(current);
var html = next.controller.render();
if (replace) {
history.replaceState(document.title, document.title, location.pathname + '#' + next.path);
} else {
history.pushState(document.title, document.title, location.pathname + '#' + next.path);
}
this._container.innerHTML = html;
(next.controller.onEnter || noop).call(next);
}
Router.prototype.eventHandler = function (e) {
this.go(new URL(e.newURL), new URL(e.oldURL), true);
}
Router.prototype.run = function () {
window.addEventListener('hashchange', this.eventHandler.bind(this), false);
this.go(window.location);
}
Router.prototype.destroy = function () {
window.removeEventListener('hashchange', this.eventHandler);
}
window.Router = Router;
})(window);