Skip to content

Latest commit

 

History

History
131 lines (80 loc) · 4.74 KB

History API.md

File metadata and controls

131 lines (80 loc) · 4.74 KB

History API

History API 允许你与浏览器历史交互,触发浏览器导航方法并更改地址栏内容。

它在与现代单页应用程序结合时特别有用,在这些应用程序上,你永远不会对新页面发出服务器端请求,而是页面始终相同:只是内部内容发生了变化。

在浏览器中运行的现代 JavaScript 应用程序如果不与 History API 交互,无论是显式的还是在框架级别上,对用户来说都将是一个糟糕的体验,因为后退和前进按钮都会中断。

此外,在浏览应用程序时,视图会发生变化,但地址栏不会

另外,重新加载按钮也会中断:由于没有深度链接,重新加载页面将使浏览器显示不同的页面。

History API 是在 HTML5 中引入的,现在所有现代浏览器都支持。

History API 支持情况

IE 从版本 10 开始支持它,如果你需要支持 IE9 及更早版本,请使用 history.js 库。

访问 History API

History API 在 window 对象上可用,因此你可以这样调用它:window.historyhistory,因为 window 它是全局对象(可以省略)。

浏览历史

window.history 对象包含浏览器的历史。

让我们从使用 History API 可以做的最简单的事情开始。

返回上一个页面:

history.back()

这将转到会话历史记录中的上一个条目。你可以使用 forward 转到下一个:

history.forward()

这就像使用浏览器的后退和前进按钮一样。

go() 允许你向后或向前导航多个深度级别。例如:

history.go(0) // 参数为 0,表示刷新页面
history.go(-1) // 相当于 history.back()
history.go(-2) // 相当于调用 2 次 history.back()
history.go(1) // 相当于 history.forward()
history.go(3) // 相当于调用 3 次 history.forward()

要想知道历史记录中有多少条目,可以调用:

history.length

向历史记录中添加条目

使用 history.pushState() 可以通过编程方式创建新的历史记录条目。

传递 3 个参数:

  • 第一个是可以包含任何内容的对象(但是有大小限制,并且对象需要可序列化)。
  • 第二个参数目前未被主要浏览器使用(查看),因此通常传递一个空字符串。
  • 第三个参数是与新状态关联的 URL。请注意,该 URL 需要属于当前 URL 的同一个源域。

以下示例将创建一条新的历史记录:

const state = { name: 'O.O' }

history.pushState(state, '', '/user')

上面代码中,将在浏览器历史记录中插入一条新的记录。

调用它不会改变页面的内容,也不会像更改 window.location 那样引起任何浏览器操作。

注意:当前页面的搜索栏会发生变化,但是不会刷新当前页面。

修改历史记录条目

history.pushState() 允许你向历史添加新状态,而 history.replaceState() 允许你编辑当前历史状态。

history.pushState({}, '', '/posts')

const state = { post: 'first' }
history.pushState(state, '', '/post/first')

const state = { post: 'second' }
history.replaceState(state, '', '/post/second')

如果你现在调用:

history.back()

浏览器直接转到 /posts,因为 /post/first/post/second 替换。

访问当前历史记录条目状态

访问属性:

history.state

其返回当前状态对象(传递给 pushStatereplaceState 的第一个参数)。

onpopstate 事件

每次活动历史状态更改时(用户前进或后退操作),都会在 window 上调用 popstate 事件,将当前状态作为回调参数:

window.addEventListener('popstate', (e) => {
  console.log(e.state) // pushState 或 replaceState 的第一个参数
})

需要注意的是,调用 history.pushState()history.replaceState() 不会触发 popstate 事件。

只有在做出浏览器动作时,才会触发该事件。例如:用户点击浏览器的前进、后退按钮,或者在 JavaScript 代码中调用 history.go()history.back()history.forward() 方法。

每次调用 history.back()history.forward()history.go() 时,都会记录新的状态对象(传递给 pushStatereplaceState 的第一个参数)。

还有一点需要注意,不同的浏览器在加载页面时处理 popstate 事件的形式存在差异。页面加载时 Chrome 和 Safari 通常会触发 popstate 事件,但 Firefox 则不会。