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>')
});
})()
複製代碼