1. 单页Web应用(single page web application,SPA)
history.back():URL回退一次
history.forward():URL前进一次
history.go(n):URL几次history.back()或几次history.forward(),比如:history.go(2):两次history.forward();history.go(-2):两次history.back();
history.length:length属性,可以查看URL的数量
2. HTML5中添加了一些方法,可以显示单页面应用
3. 方法
(1)pushState方法
history.pushState(state, title, url):将这个URL添加到历史记录中
(2)replaceState方法
history.replaceState(state, title, url):将这个URL替换当前的URL
参数:
state:一个状态对象,可以是数据对象,popstate事件触发时,会把该对象传入回调函数中;popstate事件:当历史记录发生改变时,触发该事件。
title:新页面标题,所有浏览器都忽略了该值,该值为填null。
URL:新的网址,必须和该页面处在同一个域下
注意:pushState和replaceState不刷新页面,所以,URL发生了变化,但是内容没有刷新加载,内容没有变化。
如何做?在添加或替换URL的时候,直接拼接一个“?one” “?two”、?three等等。拼接一个URL的标识。
然后在通过ajax改变网页内容,就实现了“单页面应用”
history.pushState(null, null, "?zhuyuzhu"):添加一个历史记录,空对象,空标题,拼接的URL
4. 事件
(1)popstate事件:历史记录发生改变时触发,比如:向前翻,向后翻都会触发该事件
但是:pushState和replaceState两个方法也改变了历史记录,但是不会触发popstate事件
<script>
history.pushState({name:"zhu",age:22,sex:"male"}, null, "?zhuyuzhu");
//监听popstate事件
window.addEventListener('popstate', function(e){
console.log(e);
})
</script>
注意:state对象的值,每一个URL对应自己的state值。
注意:上面代码中:history.pushState({name:"zhu",age:22,sex:"male"}, null, "?zhuyuzhu");只是将URL和state数据添加进去,要想触发popstate事件,还是要
实现SPA:注意代码中的备注
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>
* {
padding: 0px;
margin: 0px;
font-size: 0px;
}
.wrapper {
position: absolute;
left: 50%;
margin-left: -200px;
width: 400px;
height: 400px;
border: 1px solid #000;
}
.heard {
width: 100%;
display: flex;
}
button {
width: 133px;
flex-grow: 1;
height: 50px;
font-size: 20px;
}
.item {
text-align: center;
line-height: 350px;
font-size: 30px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="heard">
<button data='one'>1</button>
<button data='two'>2</button>
<button data='three'>3</button>
</div>
<div class="content">
<div class="item">88</div>
</div>
</div>
<script src="./ajax.js"></script>
<script>
var heard = document.getElementsByClassName('heard')[0];
var item = document.getElementsByClassName('item')[0];
var page = '';
var oldPage = '';
function init() {
history.replaceState({
newpage: 'one'
}, null, '?one');
ajaxFunc('GET', './getData.php', 'page=one', callback, true);
}
init();
function callback(requestData) {
console.log(requestData);
item.innerHTML = requestData;
}
heard.addEventListener('click', function (e) {
oldPage = page;
console.log(oldPage);//打印上一个page值
//获取标签内自定义的属性值
page = e.target.getAttribute('data');//将点击的标签中的data属性值,赋给page;
console.log(page);//打印新的page值
//进行判断,如果新的page值和上一个page值相等,表明用户在连续点击某一个按钮,不触发pushState事件
if(page !== oldPage){
history.pushState({
newpage: page
}, null, '?' + page);
ajaxFunc('get', './getData.php', 'page=' + page, callback, true);
}
})
//监听popstate事件
window.addEventListener('popstate', function (e) {
console.log(e);
var newpage = e.state.newpage;
console.log(newpage);
ajaxFunc('get', './getData.php', 'page=' + newpage, callback, true);
})
</script>
</body>
</html>
js部分:ajax函数
function ajaxFunc(method, url, data, callback, flag) {
//请求类型、php文件的地址、post类型需要的数据、回调函数、是否异步
var xhr = null;
if (window.XMLHttpRequest) {
//非IE
xhr = new XMLHttpRequest();
} else {
//IE
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
method = method.toUpperCase();
if(method == 'GET'){
xhr.open(method, url+'?'+ data, flag);
xhr.send();
}else if(method == 'POST'){
xhr.open(method, url, flag);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(data);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
callback(xhr.responseText);
}
}
}
}
php部分:
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);
$page = $_GET['page'];
if($page == 'one'){
$data = '111';
} else if($page == 'two'){
$data = '222';
} else if($page == 'three'){
$data = '333';
}
echo "{$data}";
?>
(2)hashchange事件
当URL中的hash值发生变化时,触发该事件
hash值:URL中# 部分
注意下面例子中,会体现a标签的特性:
(1)锚点;(2)hash值;
注意:给div加滚动条,overflow:auto;包括:overflow-x:auto和overflow-y:auto;
<!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>test</title>
<style>
.left{
position: absolute;
left: 50px;
top: 100px;
width: 150px;
height: 200px;
border: 1px solid black;
overflow: auto;
}
a{
text-decoration: none;
display: block;
width: 100px;
height: 50px;
background-color: #f3f3f3;
line-height: 50px;
text-align: center;
margin-top: 10px;
overflow: auto;
}
.right{
position: absolute;
top: 70px;
left: 300px;
border: 1px solid black;
width: 400px;
height: 500px;
overflow: auto;
}
.right div{
width: 100px;
height: 100px;
border: 1px solid black;
position: absolute;
left: 10px;
}
#one{
top:10px;
}
#two{
top: 520px;
}
#three{
top: 930px;
}
#four{
top: 1340px
}
#five{
top: 1750px;
}
</style>
</head>
<body>
<div class="left">
<a href="#one">111</a>
<a href="#two">222</a>
<a href="#three">333</a>
<a href="#four">444</a>
<a href="#five">555</a>
</div>
<div class="right">
<div id="one">1111111</div>
<div id="two">2222222</div>
<div id="three">3333333</div>
<div id="four">44444444</div>
<div id="five">5555555</div>
</div>
<script src="./ajax.js"></script>
<script>
window.addEventListener('hashchange', function(e){
console.log(111)
})
</script>
</body>
</html>