JS history对象详解

  • 内容
  • 评论
  • 相关

history 对象存储了库互动浏览器的浏览历史,通过 window 对象的 history 属性可以访问该对象,实际上 history 属性仅存储最近访问的、有限条目的 URL 信息。

在 HTML5 之前,为了保护客户端浏览信息的安全和隐私,history 对象禁止 JavaScript 脚本直接操作这些访问信息。不过 HTML5 新增了一个 History API,该 API 允许用户通过 JavaScript 管理浏览器的历史记录,实现无刷新更改浏览器地址栏的地址,配合 History + Ajax 可以设计不需要刷新页面的跳转。

操作历史记录

在历史记录中后退

window.history.back();1

这行代码等效于在浏览器的工具栏上单击“返回”按钮。

在历史记录中前进

window.history.forward();1

这行代码等效于浏览器中单击“前进”按钮。

移动到指定的历史记录点

使用 go() 方法从当前会话的历史记录中加载页面。当前页面位置索引值为 0,上一页就是 -1,下一页为 1,以此类推。

window.history.go(-1);  //相当于调用 back()
window.history.go(1);  //相当于调用forward()

length 属性

使用 length 属性可以了解历史记录栈中一共有多少页。

var num = window.history.length;

添加和修改历史记录条目

HTML5 新增 history.pushState() 和 history.replaceState() 方法,允许用户逐条添加和修改历史记录条目。

使用 history.pushState() 方法可以改变 referrer 的值,而在调用该方法后创建的 XMLHttpRequest 对象会在 HTTP 请求头中使用这个值。referrer 的值则是创建 XMLHttpRequest 对象时所处的窗口的 URL。

【示例】假设 http://123.com/foo.html 页面将执行下面 JavaScript 代码。

var stateObj = {foo : "bar"};
history.pushState (stateObj, "page 2", "bar.html");

这时浏览器的地址栏将显示 http://123.com/bar.html,但不会加载 bar.html 页面,也不会检查 bar.html 是否存在。

如果现在导航到 http://123.com/ 页面,然后单击“后退”按钮,此时地址栏会显示 http://123.com/bar.html,并且会触发 popstate 事件,该事件中的状态对象会包含 stateObj 的一个拷贝。

如果再次单击“后退”按钮,URL 将返回 http://123.com/foo.html,文档将触发另一个 popstate 事件,这次的状态对象为 null,回退同样不会改变文档内容。

pushState() 方法

pushState() 方法包含 3 个参数,简单说明如下:

  • 状态对象。状态对象是一个 JavaScript 对象直接量,与调用 pushState() 方法创建的新历史记录条目相关联。无论何时用户导航到新创建的状态,popstate 事件都会被触发,并且事件对象的 state 属性都包含历史记录条目的状态对象的拷贝。
  • 标题。可以传入一个简短的标题,标明将要进入的状态。FireFox 浏览器目前忽略该参数,考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。
  • 可选参数。新的历史记录条目的地址。

浏览器不会在调用 pushState() 方法后加载该地址,如果不指定则为文档当前 URL。

调用 pushState() 方法类似于设置 window.location='#foo',它们都会在当前文档内创建和激活新的历史记录条目。但 pushState() 有自己的优势。

  • 新的 URL 可以是任意的同源 URL。相反,使用 window.location 方法时,只有仅修改 hash 才能保证停留在相同的 document 中。
  • 根据个人需要决定是否修改 URL。相反,设置 window.location='#foo',只有在当前 hash 值不是 foo 时才创建一条新的历史记录。
  • 可以在新的历史记录条目中添加抽象数据。如果使用基于 hash 的方法,只能把相关数据转码成一个很短的字符串。

pushState() 方法永远不会触发 hashchange 事件

replaceState() 方法

history.replaceState() 与 history.pushState() 用法相同,都包含 3 个相同的参数。不同之处是:pushState() 是在 history 栈中添加一个新的条目,replaceState() 是替换当前的记录值。例如,history 栈中有两个栈块,一个标记为 1,另一个标记为 2,现在有第 3 个栈块,标记为 3。当执行 pushState() 时,栈块 3 将被添加栈中,栈就有 3 个栈块了;而当执行 replaceState() 时,将使用栈块 3 替换当前激活的栈块 2,history 的记录条数不变。也就是说,pushState() 会让 history 的数量加 1。

为了响应用户的某些操作,需要更新当前历史记录条目的状态对象或 URL 时,使用 replaceState() 方法会特别合适。

popstate 事件

每当激活的历史记录发生变化时,都会触发 popstate 事件。如果被激活的历史记录条目是由 pushState() 创建,或者是被 replaceState() 方法替换的,popstate 事件的状态属性将包含历史记录的状态对象的一个拷贝。

当浏览会话历史记录时,不管是单击浏览器工具栏中的“前进”或者“后退”按钮,还是使用 JavaScript 的 history.go() 和 history.back() 方法,popstate 事件都会被触发。

读取历史状态

在页面加载时,可能会包含一个非空的状态对象。这种情况是会发生的,例如,如果页面中使用 pushState() 或 replaceState() 方法设置了一个状态对象,然后重启浏览器。当页面重新加载时,页面会触发 onload 事件,但不会触发 popstate 事件。但是,如果读取 history.state 属性,会得到一个与 popstate 事件触发时一样的状态对象。

可以直接读取当前历史记录条目的状态,而不需要等待 popstate 事件。

var currentState = history.state;

案例:设计无刷新导航

本例设计一个无刷新页面导航,在首页(index.html)包含一个导航列表,当用户单击不同的列表项目时,首页(index.html)的内容容器(<div id="content">)会自动更新内容,正确显示对应目标页面的 HTML 内容,同时浏览器地址栏正确显示目标页面的 URL(但是首页并没有被刷新),而不是仅显示目标页面。显示效果如图所示。

 

本文标题:JS history对象详解

本文地址:http://www.hosteonscn.com/6992.html

评论

0条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注