之前写过利用Hash来实现前端路由的文章,这一篇是关于如何使用H5的history来实现一个前端路由
- Hash实现和History实现比较
-
hash
- 实现方式
是通过锚点来改变浏览器的URL,体现在URL后面会加上#,并且可以通过window.onhashChange来监听这一变化,从而我们可以建立好hash值和对应回调函数的映射关系,然后可以通过点击a标签,实现在不刷新页面情况下,通过ajax发送请求获取异步数据来改变页面的结构。 - 优点
实现方式较为简单,有现成的hashChange来监听路由哈希变化,兼容性较好,大部分浏览器支持 - 缺点
’#‘ 不太美观;由于Hash对于服务端来说是不可见的,所以对于SEO不友好;浏览器的前进后退功能受到限制
- 实现方式
-
History
- 实现方式
是通过history.pushState或者history.replaceState这样的API锚点来改变浏览器的历史记录堆栈,这个行为并不会引起页面的刷新,但是页面的URL会改变,但是和上一种方法相比,并没有方便的hashChange来监听这一变化。但是可以从3个角度来入手去控制。稍后做详细说明 - 优点
地址栏不会有#出现,可以利用浏览器的前进后退功能 - 缺点
实现需要考虑多种路由变化的情况;兼容性相对较差
- 实现方式
- 利用History具体实现前端路由思路
首先路由的切换可能由这么几个行为引起,我们需要做不同的处理。
– 点击a链接
这种方式只需要在他的onclick事件先阻止他的默认跳转行为,然后获取他的url,调用pushState/replaceState改变URL,然后根据url和回调函数的映射关系,触发相应的动作
– 直接在脚本中调用pushState/replaceState
这种方式本质上和上述相同
– 点击浏览器的前进/后退按钮,这里需要用到另一个事件,onpopState,当激活浏览器历史记录时会被触发,注意这个事件不会被pushState/replaceState触发,这个事件回调会可以获取到当前路由下,我们之前通过pushState/replaceState存入的信息,也可以拿到url信息,然后根据映射关系去执行回调。大致代码如下,提供个思路
var routeMap = {
route1:callback1,
route2:callback2,
route3:callback3
};
// 监听popState事件
window.onpopstate = function(event){
var state = event.state;
routeMap[state.route].call(this);
}
a链接如下
<a href="route1" onClick='clickHandler'> click </a>
对应的click方法大致如下
function clickHandler (event){
var route = event.target.href;
history.pushState({route:route},null,route);
routeMap[route].call(this);
return false;
}
这样一来,就实现了URL的变化,而视图的变化实际上就是callback里面的操作了,一般情况就是通过ajax去异步获取数据渲染页面结构