HTML5 history新增了两个API:history.pushState和history.replaceStatejavascript
状态对象(state object):一个JavaScript对象,与用pushState()方法建立的新历史记录条目关联。不管什么时候用户导航到新建立的状态,popstate事件都会被触发,而且事件对象的state属性都包含历史记录条目的状态对象的拷贝。css
标题(title):FireFox浏览器目前会忽略该参数,虽然之后可能会用上。考虑到将来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也能够传入一个简短的标题,标明将要进入的状态。html
地址(URL): 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但以后,可能会试图加载,例如用户重启浏览器。新的URL不必定是绝对路径;若是是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,不然,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。前端
相同之处是两个API都会操做浏览器的历史记录,而不会引发页面的刷新。不一样之处在于pushState会增长一条新的历史记录,而replaceState则会替换当前的历史记录java
window.history.pushState(null, null, "test");
window.history.pushState(null, null, "/test");
window.history.pushState(null, null, "#/hello");
window.history.pushState(null, null, "?name=");
</code></pre>
复制代码
创建html文件,index.htmljquery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>前端路由实现</title>
<style>
.warp{
width:400px;
height:400px;
border:1px solid grey;
margin:0 auto;
}
.nav{
border-bottom:1px solid grey;
}
.nav li{
display:inline-block;
list-style:none;
}
.nav li a{
display:inline-block;
text-decoration: none;
padding:10px 15px;
}
.router{
padding:20px;
}
a{
cursor: pointer;
}
</style>
</head>
<body>
<section class="warp">
<div class="nav">
<ul>
<li><a href="javascript:void(0)" data-path="index">首页</a></li>
<li><a href="javascript:void(0)" data-path="news">新闻</a></li>
<li><a href="javascript:void(0)" data-path="about">关于</a></li>
</ul>
</div>
<div id="router" class="router">
<!-- 内容加载区域 -->
</div>
</section>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="./router.js"></script>
</body>
</html>
复制代码
此时的页面为:api
引入js文件router.js浏览器
(function(){
history.replaceState(null,null,'');//最开始的状态,采用replace直接替换
$('#router').html('<p>显示内容区域</p>')
$('a').on('click',function(){
console.log(this.text)
var text = this.text;
$('#router').html('<p>'+ text +'</p>')
history.pushState(null,null,'#/'+text);
})
})()
复制代码
此时点击导航按钮时安全
// 状态版
(function(){
var count = [0,0,0]
$('#router').html('<p>首页</p>'+count[0]+'<p>新闻</p>'+count[1]+'<p>关于</p>'+count[2])
// history.replaceState(count,null,'');//最开始的状态,采用replace直接替换
for(var i = 0 ; i<$('a').length; i++){
$('a')[i].index = i
$('a').eq(i).on('click',function(){
console.log(this.index);
var index = this.index;
count[index]++;
$('#router').html('<p>首页</p>'+count[0]+'<p>新闻</p>'+count[1]+'<p>关于</p>'+count[2])
console.log(count)
history.pushState(count,null,'#/count'+count[index]);//以后的状态,须要进行保存
})
}
//监听history其余api致使地址栏url改变事件
window.addEventListener('popstate',function(e){
console.log(e.state);
var state = e.state;
$('#router').html('<p>首页</p>'+state[0]+'<p>新闻</p>'+state[1]+'<p>关于</p>'+state[2])
})
})()
复制代码
此时的思路是作一个状态记录,记录下每一个导航按钮被点击的次数。当每次执行点击导航栏切换的时候,经过history.pushState(count, null, '#/count'+count[index])这个api,传递了状态对象在内,并在第三个参数中将当前已点击数做为地址栏的显示数据。示例以下:ui
(function(){
var url = '内容展现';
history.replaceState(url,null,'');//最开始的状态,采用replace直接替换
$('#router').html('<p>'+url+'</p>')
$('a').on('click',function(){
console.log(this.text)
url = this.text;
$('#router').html('<p>'+ url +'</p>')
history.pushState(url,null,'#/'+url);
})
window.addEventListener('popstate',function(e){
console.log(e.state);
url = e.state
$('#router').html('<p>'+ url +'</p>')
});
})()
复制代码