HTML5新添加了两个API分别是pushState和replaceState,DOM中的window对象通过window.history方法提供了对浏览器历史记录的读取,可以在用户的访问记录中前进和后退,我们可以开始操作这个历史记录堆栈。
实例一、通过pushState修改URL
通过这句代码可以无刷新改变URL
window.history.pushState({}, 0, url);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>HTML5无刷修改URL</title>
<script type="text/javascript">
function changeURL(){
var url = document.getElementById('url').value;
window.history.pushState({},0,'http://'+window.location.host+'/'+url);
}
</script>
</head>
<body>
<h1>html5无刷新改变url</h1>
<div id="info" style="margin:30px 0;">
页面真实地址:
<span style="color:red;"><script type="text/javascript">document.write(window.location.href);</script></span>
</div>
<div>
请输入要改变地URL字符串:<input id='url' type="text" />
<button onclick="changeURL();">点击无刷改变url</button>
</div>
<div style="color:red;margin-top:30px;">请使用支持html5的浏览器访问</div>
</body>
</html>
在input输入框内输入newpage.html点击点击无刷新改变url
按钮即可实现
实例二、利用Ajax配合pushState翻页无刷新的动作
主要在Ajax发起数据请求,在数据页面响应后利用pushState修改分页参数,达到模拟真实翻页效果,并且写入历史表达到后退时能恢复上一页的数据
Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>HTML5无刷修改url</title>
<script type="text/javascript">
var changeURL = function(){
if(location.href.indexOf("?") > -1){
var arr = location.href.split('?');
var urlbase = arr[0];
var pageObj = arr[1].match(/page=(\d+)/);
var page = Number(pageObj[1]) || 1;
}else{
var urlbase = location.href;
var page = 1;
}
load = false;
var content = document.getElementById("content");
var ajax = new XMLHttpRequest();
// 调用数据回掉函数
var ajaxCallback = function(){
if(ajax.readyState == 4){
load = false;
result = eval('('+ajax.responseText+')');
content.innerHTML = result.data;
next.href = urlbase + "?page=" + (page + 1);
// push到历史记录里,可以在点击后退时从历史记录里恢复内容
// 并且无刷修改url地址
window.history.pushState({content:content.innerHTML,page:page},page,urlbase + "?page=" + page);
}
};
// 点击事件
document.getElementById('next').onclick = function(event){
if(!load){
load = true;
content.innerHTML = '加载中数据中...(注意看数据返回后url改变)';
page++;
ajax.open('GET','data.php?page='+page, true);
ajax.onreadystatechange = ajaxCallback;
ajax.send('');
return false;
}
};
// 记录到历史里,当点击后退按钮还退回上次页面请求前的页面内容
window.onpopstate = function(){
content.innerHTML = history.state.content;
page = history.state.page;
}
// 修改当前页面在 history 中的记录
window.history.replaceState({content:content.innerHTML,page:page},page,urlbase + (page > 1 ? '?page=' + page : '' ));
};
// 检测是否支持
try{
//监听事件
window.addEventListener('DOMContentLoaded', changeURL, false);
}catch(e){
alert('浏览器不支持,请使用支持html5的浏览器');
}
</script>
</head>
<body>
<div id="content" style="width:300px;height:100px;border:1px solid #999;">第1页的内容</div>
<div><a id="next" href="?page=2">下一页</a></div>
<div style="color:red; margin-top:30px;">请使用支持html5的浏览器测试</div>
</body>
</html>
data.php
<?php
sleep(3);
echo json_encode(array('data'=>'第'.$_GET['page'].'内容'));
最后
虽说这两个HTML5新加API能实现无刷新修改URL,但浏览器端为了安全是不能跨域的。比如本例中的Demo域是在www.qttc.net下,不能修改到www.xxx.com域下。有不少人说这个特性解决了Ajax局部刷新区域不容易被蜘蛛人抓取的问题,本人没有亲自验证,但却有可行之势,感兴趣的童鞋可以尝试下。