@xudongh
2017-05-14T15:48:39.000000Z
字数 2803
阅读 2291
前端开发
在以往的web开发中,浏览器每发出一个请求,都会传输到服务器进行处理,然后返回响应结果。
而对于使用了前端路由的页面,我们可以由浏览器预处理一些事件,当浏览器读取到一个注册到前端路由中的URL请求时,就可以直接在浏览器端响应,而不用交由服务器进行处理。前端路由被应用于spa(single page web application)页面,即单页web应用。
举个例子,有一个单页应用,URL地址为http://www.my-first-spa.com,页面上有个超链接为http://www.my-first-spa.com/page-1的事件,当我们触发这个事件时,页面不会跳转然后转到这个新的页面,而是让在这个页面进行实时更新。
所以,前端路由就是把不同的页面或者内容交给前端来进行处理,在点击浏览另一个页面时,整个页面并不会闪烁一样的刷新,在更新页面数据时,相应地改变地址栏中的url。
由于ajax异步请求技术的诞生,我们可以实现局部更新页面的功能,但其ajax会涉及到这些问题:
为了实现既能在不刷新页面的情况更新页面数据,又能相应地更新URL地址,需要用到ajax + html5的两个api。
实现前端路由需要用到html5中的两个API:
这两个方法允许我们访问并操作浏览器的历史浏览记录条目。pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录,两者传入的参数相同:
history.pushState(state object,title,URL);history.replaceState(state object,title,URL);
null即可null即可对于第三个参数URL,可传入绝对路径,也可传入相对路径,以百度首页为例,https://www.baidu.com,打开该页面,在控制台中输入:
window.history.pushState(null, null, "https://www.baidu.com?id=123");//url变化:https://www.baidu.com?id=123window.history.pushState(null, null, "https://www.baidu.com/id/123");//url变化:https://www.baidu.com/id/123window.history.pushState(null, null, "?id=123");//url变化:https://www.baidu.com?id=123window.history.pushState(null, null, "id=123");//url变化:http://www.baidu.com/id=123window.history.pushState(null, null, "/id/123");//url变化:https://www.baidu.com/id/123//错误window.history.pushState(null, null, "http://www.baidu.com?id=123");
打开浏览器的历史记录,可以看出产生几条新的历史访问记录。

但可以看到上面例子的最后一个举例,代码运行出错,这是因为这两个方法都不能跨域访问。
上面是我们所需要用到的比较基本的api。代码方面,前端路由实现的基本原理在于,通过使用hashchange事件的监听,监测url地址的变化,如果url地址发生变化,则执行响应的操作。
function Router() {this.cache = {};this.curUrl = '';this.router = function(path, callback) {this.cache[path] = callback || function() {};}this.refresh = function() {this.curUrl = location.hash.slice(1) || '/';this.cache[this.curUrl]();}this.init = function() {window.addEventListener('load', this.refresh.bind(this), false);window.addEventListener('hashchange', this.refresh.bind(this), false);}}
在上述Router对象中,一共提供了三个方法:
,为了初始化路由,需要调用Router对象:
var R = new Router();R.init();var res = document.getElementById('result');R.router('/', function() {res.style.background = '#ababab';res.innerHTML = '现在颜色为默认';});R.router('/blue', function() {res.style.background = '#1497fe';res.innerHTML = '现在颜色为blue';});R.router('/red', function() {res.style.background = '#ff5252';res.innerHTML = '现在颜色为red';});R.router('/yellow', function() {res.style.background = '#ffea94';res.innerHTML = '现在颜色为yellow';});
加上html和css代码,实现了一个更换颜色,同时会自动更新url地址的页面,例子如下:
https://codepen.io/danielxu/pen/OmQzeJ

这就是一个简单路由的实现。
在上面例子中,显然是非常简单的,但实际上路由并不是这么简单,因为要实时获取数据,那就需要ajax异步请求页面数据;同时为了满足大量url,需要对url的hash进行正则匹配处理。当然,虽然例子简单,但其前端路由的基本思路正是如此。