1. 程式人生 > 其它 >H5 History API pushState和replaceState方法

H5 History API pushState和replaceState方法

HTML5 history API

HTML5引入了history.pushState()和history.replaceState()方法。他們分別可以新增和修改歷史記錄的條目。

pushState()

history.replaceState(stateObj, title, [url])

  • stateObj:一個JavaScript物件,可以是任何可以序列化的物件。它與建立的新歷史記錄條目相關聯。每當使用者導航到新狀態時,都會觸發popstate事件(下面會講)。

  • title:簡短的標題(大部分瀏覽器都忽略了該引數)。

  • url:歷史記錄條目的URL。

瀏覽器為每個頁面維護一個History棧。當執行pushState()指標所在的位置在棧頂時,會保留當前歷史記錄並新增一條新的歷史記錄條目並壓入棧頂,同時修改指標指向新記錄,History棧大小會增加。
當執行pushState()指標所在的位置不在棧頂在棧中間時,會將指標上面的記錄移除並新增一條新的記錄並壓入棧頂。
當執行back(返回上一頁)操作時,指標會移動到之前的一條記錄,但是棧不會發生變化。

測試demo:


<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<button id="btn1">pushState</button>
		<button id="btn2">getLen</button>
		<span></span>
	</body>
	<script src="./js/jquery.min.js"></script>
	<script>
		$(document).ready(function() {

			let i = 1;
			$('span').html('當前歷史記錄棧中的總條目數:' + history.length);

			$('#btn1').on('click', () => {
				history.pushState({}, '', 'test' + i + '.html');
				i++;
			});

			$('#btn2').on('click', () => {
				$('span').html('當前歷史記錄棧中的總條目數:' + history.length);
			});

		});
	</script>
</html>

replaceState()

history.replaceState(stateObj, title, [url])

replaceState()會將當前記錄修改成指定的URL,但不會改變指標。

測試demo:


<body>
		<button id="btn1">pushState</button>
		<button id="btn2">replaceState</button>
		<button id="btn3">getLen</button>
		<span></span>
	</body>
	<script src="./js/jquery.min.js"></script>
	<script>
		$(document).ready(() => {

			let i = 1;
			$('span').html('當前歷史記錄棧中的總條目數:' + history.length);

			$('#btn1').on('click', () => {
				history.pushState({}, '', 'test' + i + '.html');
				i++;
			});
			
			$('#btn2').on('click', () => {
				history.replaceState({}, '', 'test' + i + '.html');
				i++;
			});

			$('#btn3').on('click', () => {
				$('span').html('當前歷史記錄棧中的總條目數:' + history.length);
			});

		});
	</script>

popstate事件

popstate也是H5 History API 新增的一個介面,主要用於控制歷史記錄條目。

當歷史記錄條目更改時,將觸發popstate事件。當用戶在瀏覽器點選進行後退、前進,或者在js中呼叫histroy.back(),history.go(),history.forward()等,會觸發popstate事件。但history.pushState()、history.replaceState()不會觸發這個事件。

測試demo:


<body>
		<button id="btn1">pushState</button>
		<button id="btn2">replaceState</button>
		<button id="btn3">forward</button>
		<button id="btn4">back</button>
		<span></span>
	</body>
	<script src="./js/jquery.min.js"></script>
	<script>
		$(document).ready(() => {

			let i = 1;

			$('#btn1').on('click', () => {
				history.pushState({page: i}, '', 'test' + i + '.html');
				i++;
			});

			$('#btn2').on('click', () => {
				history.replaceState({page: i}, '', 'test' + i + '.html');
				i++;
			});

			$('#btn3').on('click', () => {
				history.forward();
			});

			$('#btn4').on('click', () => {
				history.back();
			});
			
			window.addEventListener('popstate', (event) => {
			  console.log("state: " + JSON.stringify(event.state));
			});

		});
	</script>

vue-router History 模式

前端路由最主要的特點就是通過改變URL,在不請求頁面的情況下,更新頁面檢視。HTML5 history API 新增的兩個方法就為此提供了方便。
vue-router 預設hash模式,使用URL的hash來模擬一個完整URL。hash為符號#及後面的字元,如URLhttp://localhost:8080/#/Home,hash就是#/Home。hash不會包括在http請求中,所以修改hash內容不會重新請求頁面。

history模式下則通過使用history.pushState API來完成URL跳轉而無須重新載入頁面。通過上面的demo我們可以看到,使用history.pushState()和history.replaceState()無論URL怎麼改變頁面都只是修改了檢視,但是不會發送新的請求。一旦我們重新整理一下頁面就會發現404資原始檔不存在,不存在指定的html檔案。