相識
HTML5 history
新增了兩個API
:history.pushState
和history.replaceState
兩個API
都吸收三個參數:
- 狀況對象(
state object
):一個JavaScript對象,與用pushState()
要領建立的新汗青記錄條目關聯。不管什麼時刻用戶導航到新建立的狀況,popstate
事宜都邑被觸發,而且事宜對象的state屬性都包括汗青記錄條目的狀況對象的拷貝。 - 題目(
title
):FireFox瀏覽器現在會疏忽該參數,雖然今後能夠會用上。考慮到將來能夠會對該要領舉行修正,傳一個空字符串會比較平安。或許,你也能夠傳入一個簡短的題目,標明將要進入的狀況。 - 地點(
URL
): 新的汗青記錄條目的地點。瀏覽器不會在挪用pushState()
要領后加載該地點,但以後,能夠會試圖加載,比方用戶重啟瀏覽器。新的URL不一定是絕對路徑;假如是相對路徑,它將以當前URL為基準;傳入的URL與當前URL應該是同源的,不然,pushState()
會拋出非常。該參數是可選的;不指定的話則為文檔當前URL。
相同之處是兩個 API
都邑操縱瀏覽器的汗青記錄,而不會引發頁面的革新。
不同之處在於pushState
會增添一條新的汗青記錄,而replaceState
則會替代當前的汗青記錄。
這裏人人能夠先F12
嘗嘗,看看地點欄發生了什麼變化
window.history.pushState(null, null, "hell");
window.history.pushState(null, null, "/hell");
window.history.pushState(null, null, "#/hello");
window.history.pushState(null, null, "?name=");
注重:這裏的url不支持跨域,不然會拋出非常
嘗試
index.html
<!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>
一:簡樸開胃菜
router.js
;(function(){
history.replaceState(null,null,'');//最最先的狀況,採納replace直接替代
$('#router').html('<p>nav1</p>')
$('a').on('click',function(){
console.log(this.text)
var text = this.text;
$('#router').html('<p>'+ text +'</p>')
history.pushState(null,null,'#/'+text);
})
})()
最簡樸的示例,只能監聽點擊事宜,而瀏覽器中的后、行進都不能監聽地點欄的轉變
二、數據狀況治理
router.js
狀況版
;(function(){
var count = [0,0,0]
$('#router').html('<p>導航1:</p>'+count[0]+'<p>導航2:</p>'+count[1]+'<p>導航3:</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>導航1:</p>'+count[0]+'<p>導航2:</p>'+count[1]+'<p>導航3:</p>'+count[2])
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>導航1:</p>'+state[0]+'<p>導航2:</p>'+state[1]+'<p>導航3:</p>'+state[2])
})
})()
popstate
當運動汗青記錄條目更改時,將觸發popstate事宜。假如被激活的汗青記錄條目是經由過程對history.pushState()的挪用建立的,或許遭到對history.replaceState()的挪用的影響,popstate事宜的state屬性包括汗青條目的狀況對象的副本。
須要注重的是挪用history.pushState()或history.replaceState()不會觸發popstate事宜。只要在做出瀏覽器行動時,才會觸發該事宜,如用戶點擊瀏覽器的回退按鈕(或許在Javascript代碼中挪用history.back())
三:回歸簡樸
router.js
;(function(){
var url = 'nav1';
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>')
});
})()
兜兜轉轉我們算是回到了出發點,然則經由過程這張圖我們會發明頁面點擊革新按鈕會有導航和內容塊不一致的內容,所以我們須要革新他,而且監聽load
事宜
革新
;(function(){
$('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>')
});
window.addEventListener('load',function(){
url = location.hash.slice(2) || 'nav1';
history.replaceState(url,null,'');
console.log(location.hash);
$('#router').html('<p>'+ url +'</p>');
});
})()
能夠看到我們點擊革新的時刻導航和內容地區一致了。
四:路由頁面引進
我們這裏照樣採納了ajax
的load
要領
router.js
;(function(){
var router = [
{
'path':'index',
'url':'./main.html'
},
{
'path':'news',
'url':'./news.html'
},
{
'path':'about',
'url':'./about.html'
}
];
//轉變頁面
function display_page(url){
$('#router').load(url)
}
$('a').on('click',function(){
var path = $(this).data('path');
console.log(path)
for(var i in router){
if(router[i].path == path){
display_page(router[i].url);
history.pushState(router[i].url,null,router[i].path);
}
}
})
window.addEventListener('popstate',function(e){
var url = e.state;
display_page(url);
});
window.addEventListener('load',function(){
var start = location.href.lastIndexOf('/');
var path = location.hash.slice(start) || 'index';
console.log(path)
for(var i in router){//革新 加載
console.log(1)
if(router[i].path == path){
display_page(router[i].url);
history.replaceState(router[i].url,null,path);
break;
}
if(i == router.length-1){//重定向
display_page(router[0].url);
history.replaceState(router[i].url,null,router[0].path);
}
}
});
})()
能夠看到基本是完成了history
路由功用,然則這裡有一個題目就是革新后因為地點欄url緣由會報錯,也就是找不到這個頁面,這是因為革新的時刻是重載,從新向網站目次查找文件,而我們當前目次並沒有這個文件資本所以致使報錯。須要背景阻攔! 摒棄!
折衷
末了我照樣屈服於#
了
;(function(){
var router = [
{
'path':'index',
'url':'./main.html'
},
{
'path':'news',
'url':'./news.html'
},
{
'path':'about',
'url':'./about.html'
}
];
//轉變頁面
function display_page(url){
$('#router').load(url)
}
$('a').on('click',function(){
var path = $(this).data('path');
console.log(path)
for(var i in router){
if(router[i].path == path){
display_page(router[i].url);
history.pushState(router[i].url,null,'#/'+router[i].path);
}
}
})
window.addEventListener('popstate',function(e){
var url = e.state;
display_page(url);
});
window.addEventListener('load',function(){
var path = location.hash.slice(2) || '/index';
console.log(path)
for(var i in router){//革新 加載
console.log(1)
if(router[i].path == path){
display_page(router[i].url);
history.replaceState(router[i].url,null,'#/' + path);
break;
}
if(i == router.length-1){//重定向
display_page(router[0].url);
history.replaceState(router[0].url,null,'#/' + router[0].path);
}
}
});
})();
委曲的很呀
代碼: router(history)
演示: 演示地點