diff --git a/LinkedList.js b/LinkedList.js new file mode 100644 index 0000000..d154b6f --- /dev/null +++ b/LinkedList.js @@ -0,0 +1,69 @@ +function ListNode (id, router, prev, next) { + this.id = id; + this.router = router; + this.prev = prev; + this.next = next; +} + +function LinkedList(capacity) { + this.head = new ListNode(null, null); + this.tail = new ListNode(null, null); + this.head.next = this.tail; + this.tail.prev = this.head; + this.LinkedListMap = {}; + this.capacity = capacity; + this.size = 0; +} + +LinkedList.prototype.push = function (route, id) { + let node = this.LinkedListMap[id]; + if (!node || node.next === this.tail){ + // 正常的push + if (this.size === this.capacity) { + this._remove(this.head.next); + } + } else { + // 处理当前currentRoute不是最后一个情况下的push,将当前节点后面的路由删除掉 + node.next = this.tail; + this.tail.prev = node; + } + return this._add(route); +} + +LinkedList.prototype._remove = function (route) { + route.prev.next = route.next; + route.next.prev = route.prev; + delete this.LinkedListMap[route.id]; + return route; +} + +LinkedList.prototype._add = function (route) { + var tail = this.tail; + var prev = tail.prev; + var node = new ListNode(route.id, route, prev, tail); + this.LinkedListMap[route.id] = node; + prev.next = node; + tail.prev = node; + return node; +} + +LinkedList.prototype.remove = function(id) { + let route = this.LinkedListMap[id]; + this._remove(route); +} + +LinkedList.prototype.forward = function (id) { + let route = this.LinkedListMap[id]; + if (route.next && route.next !== this.tail) { + return route.next; + } +} + +LinkedList.prototype.back = function (id) { + let route = this.LinkedListMap[id]; + if (route.prev && route.prev !== this.head) { + return route.prev.router; + } +} + +module.exports = LinkedList; \ No newline at end of file diff --git a/router.js b/router.js index d8926ea..664bb06 100644 --- a/router.js +++ b/router.js @@ -1,27 +1,55 @@ +const LinkedList = require('./LinkedList'); + function Router(routes, defaultRoute) { //TODO + this._ROUTE_MAP = {}; + routes.forEach((item) => { + var pageId = item.id; + if (pageId) { + this._ROUTE_MAP[pageId] = item; + } + }); + + // 通过带索引的链表模拟history,不用关心数组的下标和来回切换上下的访问 + this.routerHistory = new LinkedList(5); + if (defaultRoute) { + this.push(defaultRoute); + } } //初始化,可多次初始化 Router.prototype.init = function(routes, defaultRoute) { //TODO - this.currentRoute - this.oldRoute } //切换路由 Router.prototype.push = function(route, callback) { //TODO + if (this._ROUTE_MAP[route]) { + this.routerHistory.push(this._ROUTE_MAP[route], this.currentRoute && this.currentRoute.id, ); + this._enter(route) + return callback && callback(); + } +} + +Router.prototype._enter = function(route) { + var router = this._ROUTE_MAP[route]; + this.currentRoute = router; + if (router.handler) { + router.handler(); + } } //前进 Router.prototype.forward = function () { - history.forward(); + var forward = this.routerHistory.forward(this.currentRoute.id); + this.currentRoute = forward; } //后退 Router.prototype.back = function () { - history.back(); + var back = this.routerHistory.back(this.currentRoute.id); + this.currentRoute = back; } //切换页面:route为字符串,为空则隐藏所有路由 @@ -29,4 +57,11 @@ Router.prototype.changePage = function(route) { //TODO } -module.exports = Router \ No newline at end of file +Router.prototype.replace = function (id) { + let route = this._ROUTE_MAP[id]; + this.routerHistory.remove(this.currentRoute.id); + this.routerHistory.push(route); + this.currentRoute = route; +} + +module.exports = Router; \ No newline at end of file diff --git a/test/index.spec.js b/test/index.spec.js index 27b7c39..1099f87 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,3 +1,4 @@ +const Router = require('../router.js'); describe('初始化路由', () => { it('default route', () => { //路由表