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文件。

posted @ 2021-11-11 18:13  可爱的黑精灵  阅读(769)  评论(0编辑  收藏  举报