---恢復內容開始---
在移動端,越來越傾向於頁面內跳轉,而頁面內跳轉就需要用到history的管理,html5的history是一種解決方案。
在沒有history ap之前,我們經常使用散列值來改變頁面內容,特別是那些對頁面特別重要的內容。因為沒有刷新,所以對於單頁面應用,改變其URL是不可能的。此外,當你改變URL的散列值,它對瀏覽器的歷史記錄沒有任何影響。通過增加location.hash,並用onhashchange來達到目的。
現在對於HTML 5的History API來說,這些都是可以輕易實現的,但是由於單頁面應用沒必要使用散列值,它可能需要額外的開發腳本。它也允許我們用一種對SEO友好的方式建立新應用。
使用history
HTML 5提供了兩個新方法:pushstate跟replaceState,兩個方法參數一樣
params {
state:存儲JSON字符串,可以用在popstate事件中,可以通過locaton.state獲取。
title:現在大多數瀏覽器不支持或者忽略這個參數,最好用null代替
url:任意有效的URL,用於更新瀏覽器的地址欄,並不在乎URL是否已經存在地址列表中。更重要的是,它不會重新加載頁面。
}
兩個方法的主要區別就是:pushState()是在history棧中添加一個新的條目,replaceState()是替換當前的記錄值。用pushState的時候會產生一條新的history,replaceState則不會產生。
當我們使用pushState()和replaceState()進行處理時或者點擊瀏覽器的前進后退的時候,popstate事件會被觸發,通過監聽popstate事件可以達到一系列功能。
瀏覽器支持
history在某些瀏覽器上支持還不是特別好,可以引用這個實現兼容的js
https://github.com/browserstate/history.js
案例DEMO
通過點擊頁面的導航,實現頁面內跳轉,根據popstate監聽URL的改變顯示不同的頁面.
這種路由方式還需要服務器端的支持,不然刷新頁面會出現404
如果入口是index,apache可以在根目錄下建個.htaccess文件,配置如下,
RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L]
如果你用的ngnix,配置如下
server {
...
location / {
try_files $uri /index.html;
}
}
index.html
<!DOCTYPE html> <html> <head> <title>History API</title> <meta charset="utf-8" /> </head> <body> <ul id="menu"> <li><a href="/home">首頁</a></li> <li><a href="/about">關於我們</a></li> <li><a href="/blog">博客</a></li> <li><a href="/photos">相冊</a></li> </ul> <button id="back">Back</button> <button id="forward">Forward</button> <div> Action: <span id="action"></span><br/> Url: <span id="url"></span><br/> Description: <span id="description"></span> </div> </body> </html>
js代碼
document.addEventListener('DOMContentLoaded', function(){
var act, historyState;
var menu = document.querySelectorAll('li a');
historyState = {
home : {
description : "我是首頁------Index Page"
},
about : {
description : "關於我們------About Page"
},
blog : {
description : "博客頁面------Blog Page"
},
photos : {
description : "相冊頁面------Photos Page"
}
};
for( let i =0; i < menu.length; i++ ) {
menu[i].addEventListener('click', function(e){
e.preventDefault();
var hash = menu[i].getAttribute('href');
var key = hash.replace('/','');
act = "點擊導航";
historyState[key].url = key;
//history.pushState(historyState[key], null, hash);
history.replaceState(historyState[key], null, hash);
setStateInfo( historyState[key] );
},false);
}
window.addEventListener('popstate', function(event){
var state = history.state || event.state || window.event.state;
if( state) setStateInfo(state);
},false);
document.querySelector("#back").addEventListener('click', function(){
act = "點擊后退按鈕";
history.back();
}, false);
document.querySelector("#forward").addEventListener('click', function(){
act = "點擊前進按鈕";
history.go(1);
});
function setStateInfo( state ){
//ajax處理不同的數據
document.querySelector('#action').innerHTML = act;
document.querySelector("#url").innerHTML = state.url;
document.querySelector('#description').innerHTML = state.description;
}
//第一次加載進來的時候
var path = location.pathname;
var arr = path.split('/');
var index = arr[arr.length - 1] || 'home'
act = "刷新頁面";
historyState[index].url = index;
setStateInfo(historyState[index]);
//history.pushState(historyState[index], null, '/home')
history.replaceState(historyState[index], null, hash);
},false);
通過切換就可以達到頁面跳轉和ajax刷新的效果,而不再出現hash散列值


---恢復內容結束---
