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>