---恢复内容开始---
在移动端,越来越倾向于页面内跳转,而页面内跳转就需要用到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散列值


---恢复内容结束---
