前端单页面应用路由
单页面应用中,路由由前端控制,前端实现路由主要有两种方式:
- 一是HTML5推出的history API,由pushState()记录操作历史,监听popstate事件来进行视图切换;
- 二是使用hash值,通过监听hashchange事件来进行视图切换
以下是一个路由示例:
<div id="route"> <a href="#/page1">page1</a> <a href="#/page2">page2</a> <a href="#/page3">page3</a> </div> <div id="content"></div>
var util = { history: !!window.history && window.history.pushState, hashchange: 'onhashchange' in window } window.onload = function () { var router = new Router(); // 路由配置 router.when('/page1', { template: '<h1>page1</h1>' }).when('/page2', { template: '<h1>page2</h1>' }).when('/page3', { template: '<h1>page3</h1>' }).otherwise('/page1') router.fireUrlChange(); if(util.history) { // 页面地址改变,更新页面 $(window).on('popstate', function () { router.fireUrlChange(); }) } if(util.hashchange) { // hash值改变时更新页面 $(window).on('hashchange', function () { router.fireUrlChange(); }); } } function Router() { this.routers = {}; } Router.prototype = { constructor: Router, /** * 添加路由 * @param path * @param route * @returns {Router} */ when: function (path, route) { this.routers[path] = route; return this; }, /** * 首次加载路由 * @param url */ otherwise: function (url) { this.newUrl = url; }, /** * 路由改变时触发 */ fireUrlChange: function () { // 首次加载otherwise路由 if(!location.hash) { if(util.history) { history.pushState(null, '', location.href+'#'+this.newUrl); } if(util.hashchange) { location.hash = this.newUrl; } } this.newUrl = location.hash.substring(1); // 路由没有变化 if(this.newUrl === this.lastUrl) { return; } // 路由发生变化 this.lastUrl = this.newUrl; //更新页面 var $content = $('#content'); $content.html(this.routers[this.newUrl].template); } }