前端实现有两个页面page1和page2,page1跳转到page2,page2点击浏览器自带回退按钮回退到page1时,通过浏览器history api 给page1界面传递信息
我们使用浏览器 History API 来实现页面回退时传递信息的功能。与 localStorage
相比,History API 更适合处理页面间的状态信息,并且不会在浏览器存储中留下数据。
核心思路:
-
Page1 跳转到 Page2:
- 在跳转到 Page2 时,使用
history.pushState()
方法添加一个状态对象,其中包含一个标识符(例如,page1_visited=true
)和一个用于传递信息的数据字段(初始值为空)。
- 在跳转到 Page2 时,使用
-
Page2 监听回退:
- 在 Page2 中,监听浏览器的
popstate
事件。 - 当
popstate
事件触发时,如果历史记录中的state
属性有page1_visited
为true
的记录,则表示从 Page1 而来。 - 更新
state
中的数据字段,并使用history.replaceState()
更新当前页面的历史记录状态,将信息传递给 Page1。
- 在 Page2 中,监听浏览器的
-
Page1 监听
popstate
:- 在 Page1 中,同样监听
popstate
事件。 - 当
popstate
事件触发时,检查event.state
是否存在需要传递的信息,如果有则使用。
- 在 Page1 中,同样监听
代码实现:
Page1 (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Page 1</title>
</head>
<body>
<h1>Page 1</h1>
<p id="message-display">Message from Page 2: </p>
<button id="go-to-page2">Go to Page 2</button>
<script>
const messageDisplay = document.getElementById('message-display');
const goToPage2Button = document.getElementById('go-to-page2');
// 监听浏览器 popstate 事件
window.addEventListener('popstate', (event) => {
if (event.state && event.state.messageFromPage2) {
messageDisplay.textContent = `Message from Page 2: ${event.state.messageFromPage2}`;
}else {
messageDisplay.textContent = 'Message from Page 2: No message received.';
}
});
// 跳转到 Page 2
goToPage2Button.addEventListener('click', () => {
const state = { page1_visited: true, messageFromPage2: '' };
history.pushState(state, '', 'page2.html');
window.location.href = 'page2.html';
});
</script>
</body>
</html>
Page2 (page2.html):
<!DOCTYPE html>
<html>
<head>
<title>Page 2</title>
</head>
<body>
<h1>Page 2</h1>
<p>This is Page 2.</p>
<script>
// 监听浏览器回退/前进事件
window.addEventListener('popstate', (event) => {
if (event.state && event.state.page1_visited) {
// 传递信息
const message = 'Hello from Page 2!';
const newState = {...event.state, messageFromPage2: message}
history.replaceState(newState, ''); // 更新历史记录状态
}
});
</script>
</body>
</html>
代码讲解:
Page1 (index.html):
messageDisplay
和goToPage2Button
: 获取页面上的元素。popstate
事件监听:- 监听浏览器的
popstate
事件,这个事件在点击回退或前进按钮时触发。 - 检查
event.state
是否存在,并且event.state
对象中是否存在messageFromPage2
属性,如果有,则展示信息。
- 监听浏览器的
goToPage2Button
点击事件:- 创建
state
对象,包含page1_visited
标识和用于传递数据的messageFromPage2
。 - 使用
history.pushState(state, '', 'page2.html')
将state
对象添加到历史记录中,并通过window.location.href
跳转到page2.html
。
- 创建
Page2 (page2.html):
popstate
事件监听:- 监听浏览器的
popstate
事件。 - 检查
event.state
是否存在,且event.state
对象中是否存在page1_visited
属性。 - 创建新的
newState
对象,把需要传递的信息赋值给messageFromPage2
字段。 - 使用
history.replaceState(newState, '')
更新当前页面的历史记录状态。
- 监听浏览器的
关键点总结:
history.pushState(state, title, url)
:- 用于向浏览器的历史记录添加一个状态。
state
:状态对象,可以是任意 JavaScript 对象。title
:页面的标题(大多数浏览器会忽略)。url
:新页面的 URL。
history.replaceState(state, title)
:- 用于替换当前历史记录条目的状态。
state
:新的状态对象。title
:页面的标题(大多数浏览器会忽略)。
popstate
事件: 当浏览器历史记录发生变化(通常是点击回退或前进按钮)时触发。event.state
: 在popstate
事件中,event.state
包含了当前历史记录条目的状态对象。
注意事项:
- History API 依赖浏览器的历史记录,如果用户直接在地址栏中输入URL,或者使用非浏览器方式导航,可能不会触发
popstate
事件。 - History API 只能传递简单的状态对象,不能传递复杂的对象或者函数,必要时需要进行序列化和反序列化。
- 使用 History API 不会发起新的 HTTP 请求,只会更新浏览器的历史记录状态。
对比 localStorage
:
- History API:
- 更适合管理页面间的状态信息。
- 数据只在会话期间存在,不会长期存储。
- 数据直接保存在历史记录中,方便获取。
localStorage
:- 更适合存储持久化的数据。
- 数据在浏览器关闭后仍然存在。
- 需要手动清理。
总的来说,如果只是需要在页面跳转回退时传递信息,使用 History API 更加优雅和自然。
点滴积累
当用户点击浏览器的前进或后退按钮时,浏览器会先触发 popstate
事件,然后再进行页面的前进或后退操作。以下是详细的解释:
事件触发顺序:
-
用户点击前进/后退按钮:
- 用户在浏览器中点击前进或后退按钮。
-
popstate
事件触发:- 浏览器会立即触发当前页面的
popstate
事件。这个事件的触发不会导致页面重新加载,而是会通知当前页面,浏览器的历史记录发生了变化。 popstate
事件的event
对象包含state
属性,其中存储了该历史记录条目的状态对象(如果使用history.pushState
或history.replaceState
添加了状态的话)。
- 浏览器会立即触发当前页面的
-
页面状态更新(可选):
- 在
popstate
事件的监听器中,你可以根据event.state
的值来更新当前页面的状态,比如改变页面上的某些数据或 UI 显示。 - 如果你使用了
history.pushState
或history.replaceState
修改了历史记录,那么你可以在popstate
事件中利用event.state
来恢复对应的状态。 - 需要注意的是,此时页面并没有真正刷新或者重新加载。
- 在
-
页面前进/后退:
- 在
popstate
事件处理完毕后,浏览器才会真正地前进或后退到相应的页面。 - 如果前进/后退的页面没有被缓存,浏览器会进行页面的重新渲染或加载。
- 如果前进/后退的页面被缓存,浏览器会从缓存中读取,会触发该页面的
pageshow
事件,并且此时的pageshow
事件中的event.persisted
属性会被设置为 true。 - 如果用户点击回退或者前进时,页面没有产生缓存,则会触发新页面的
load
事件。
- 在
popstate
事件的特点:
- 不引起页面重载:
popstate
事件的触发不会导致页面的重新加载或刷新。它只是通知当前页面,历史记录发生了变化。 - 可以获取历史状态:
event.state
属性允许你获取与历史记录条目相关联的状态对象,这对于实现单页应用 (SPA) 的路由非常有用。 - 在
pushState
或replaceState
之后才会触发: 只有使用了history.pushState
或history.replaceState
修改了浏览器的历史记录,且用户点击了前进/后退按钮时,才会触发popstate
事件。
pageshow
事件的特点:
- 可以监听缓存页面:
pageshow
事件允许你监听页面是从浏览器缓存加载的情况。 event.persisted
属性: 该属性标识了当前页面是否是从缓存加载。
理解这个执行顺序对于正确处理单页应用中的路由和页面状态非常重要。 使用 popstate
事件,可以无缝地更新页面内容,实现更加流畅的用户体验。