@xudongh
2017-05-14T23:48:39.000000Z
字数 2803
阅读 2088
前端开发
在以往的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=123
window.history.pushState(null, null, "https://www.baidu.com/id/123");
//url变化:https://www.baidu.com/id/123
window.history.pushState(null, null, "?id=123");
//url变化:https://www.baidu.com?id=123
window.history.pushState(null, null, "id=123");
//url变化:http://www.baidu.com/id=123
window.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进行正则匹配处理。当然,虽然例子简单,但其前端路由的基本思路正是如此。