前端路由简介
在单页面应用(SPA)中,路由模块起到一个很重要的作用:既然是单页面也就不存在刷新,那么不同功能视图的切换就需要通过路由。我认为路由就是依靠ajax,不刷新页面,依靠重新绘制DOM来实现视图的切换。
前端路由有两种实现方式:hash和H5
hash
<ul>
<li><a href="#/">首页</a></li>
<li><a href="#/product">产品</a></li>
<li><a href="#/server">服务</a></li>
</ul>
href属性表示点击该元素时,链接出去的url。如果该url带有'#'符号,则不会跳转到其他页面,'#'符号可理解为锚点或书签,它只在该页面内进行跳转。
锚点的符号必须为#,在#后面,可以不加任何东西,那么页面会默认回到最顶端;也可以加一些url,url也并不是一定要以开头。另外,我们点击锚点的操作也会被记录到浏览器的历史记录里面,按返回就可以回到上一个锚点处。
那我们应该如何利用锚点这个特性做到单页路由:当页面的hash值改变时,会在window对象上产生hashchange事件,那么我们监听该事件,就能获得改变的hash,进而重绘DOM。
下面就是一个简单的用hash做路由的完整例子,路由系统用对象Router实现,该对象主要提供三个方法:
init:监听浏览器的hashchange事件。
route:根据不同的url分配不同的回调函数。
refresh:执行当前url对应的回调函数,更新页面。
<ul>
<li><a href="#/">首页</a></li>
<li><a href="#/product">产品</a></li>
<li><a href="#/server">服务</a></li>
</ul>
<div id="result"></div>
<script type="text/javascript">
function Router(){
this.routes = {};
this.curUrl = '';
this.route = function(path, callback){
this.routes[path] = callback || function(){};
};
this.refresh = function(){
this.curUrl = location.hash.slice(1) || '/';
this.routes[this.curUrl]();
};
this.init = function(){
window.addEventListener('load', this.refresh.bind(this), false);
window.addEventListener('hashchange', this.refresh.bind(this), false);
}
}
var R = new Router();
R.init();
var res = document.getElementById('result');
R.route('/', function() {
res.style.background = 'blue';
res.innerHTML = '这是首页';
});
R.route('/product', function() {
res.style.background = 'orange';
res.innerHTML = '这是产品页';
});
R.route('/server', function() {
res.style.background = 'black';
res.innerHTML = '这是服务页';
});
</script>
HTML5
下面使用H5的API来实现路由:如果单单是切换视图,使用DOM重绘就可以,但涉及到历史记录,就需要使用history.pushState
这个API。
<!DOCTYPE HTML>
<!-- this starts off as http://example.com/line?x=5 -->
<title>Line Game - 5</title>
<p>You are at coordinate <span id="coord">5</span> on the line.</p>
<p>
<a href="?x=6" onclick="go(1); return false;">Advance to 6</a> or
<a href="?x=4" onclick="go(-1); return false;">retreat to 4</a>?
</p>
<script>
var currentPage = 5; // prefilled by server!!!!
function go(d) {
setupPage(currentPage + d);
history.pushState(currentPage, document.title, '?x=' + currentPage);
}
onpopstate = function(event) {
setupPage(event.state);
}
function setupPage(page) {
currentPage = page;
document.title = 'Line Game - ' + currentPage;
document.getElementById('coord').textContent = currentPage;
document.links[0].href = '?x=' + (currentPage+1);
document.links[0].textContent = 'Advance to ' + (currentPage+1);
document.links[1].href = '?x=' + (currentPage-1);
document.links[1].textContent = 'retreat to ' + (currentPage-1);
}
</script>
小结
比较 | hash | H5 |
---|---|---|
历史记录 | 锚点自动记录 | 使用pushState人为加入记录 |
url形式 | 带有# | 可以不带特殊符号 |
兼容性 | 全部兼容 | 支持H5的才兼容 |
【Reference】
1.Javascript实现前端简单路由 http://www.helloweba.com/view-blog-385.html
2.Web开发中前端路由实现的几种方式和适用场景 http://blog.csdn.net/xllily_11/article/details/51820909