仓库源文站点原文


title: HTML5 History API 和 Location 对象剖析 layout: post thread: 180 date: 2017-08-20 author: Joe Jiang categories: Document tags: [DOM, JavaScript, History, Location]

excerpt: 这次也不长篇大论,只搞清楚两件事 —— History API & Location 对象。了解清楚这些,将能够使我们在不同 web 页面之间穿梭自如。

这次也不长篇大论,只搞清楚两件事 —— History API & Location 对象。了解清楚这些,将能够使我们在不同 web 页面之间穿梭自如。

History API

History 作为一个全局变量(即 window.history),不继承任何属性,在 HTML4 时代就已经存在,通过这个接口,我们可以操纵浏览器中曾经访问过的会话历史记录,但当时我们能使用的属性与方法只有这么几个:

从 HTML5 开始,增加了两个新的方法:

至此,这个 API 拥有的方法就都梳理完了。但是刚刚说到了 state 对象关联的一个事件,所以在这里把 popstate 事件也描述一下。

window.onpopstate = function(event) {
  alert("location: " 
    + document.location 
    + ", state: " 
    + JSON.stringify(event.state));
};

大致上看,history API 的支持情况还是很不错的,可以点击此处查看各个浏览器对 history 的支持情况。

Location 对象

当然,当我们更改URL时,可能会出现这样一种情况:我们只更改了URL的片段标识符 (跟在#符号后面的URL部分,包括#符号),这种情况下将触发 hashchange 事件,使用方法如下:

window.addEventListener("hashchange", funcRef, false);

// 或者

window.onhashchange = funcRef;

其中,提到的 hash 属性可以通过 location.hash 获得。从这里开始,我们引出 Location 对象。Location 对象包含有关当前 URL 的信息。针对一个示例 http://b.a.com:88/index.php?name=kang&when=2011#first 我们整理一下各个属性与其含义的分别所指内容是啥。

属性 描述
hash 设置或返回从井号 (#) 开始的 URL(锚)。 "#first"
host 设置或返回主机名和当前 URL 的端口号。 "b.a.com:88"
hostname 设置或返回当前 URL 的主机名。 "b.a.com"
href 设置或返回完整的 URL。 "http://b.a.com:88/index.php?name=kang&when=2011#first"
pathname 设置或返回当前 URL 的路径部分。 "/index.php"
port 设置或返回当前 URL 的端口号。 88
protocol 设置或返回当前 URL 的协议。 "http:"
search 设置或返回从问号 (?) 开始的 URL(查询部分)。 "?name=kang&when=2011"

window.location和document.location互相等价的,可以交换使用。且 location 的8个属性都是可读写的,但是只有href与hash的写才有意义。例如改变location.href会重新定位到一个URL,而修改location.hash会跳到当前页面中的anchor名字的标记(如果有),而且页面不会被重新加载。

通过 location 我们可以作如下几种方法的操作:

导航到一个新页面的方法:

window.location.assign("http://www.mozilla.org"); // or
window.location = "http://www.mozilla.org";

针对 reload 需要说明的是,如果该方法没有规定参数,或者参数是 false,它就会用 HTTP 头 If-Modified-Since 来检测服务器上的文档是否已改变。如果文档已改变,reload() 会再次下载该文档。如果文档未改变,则该方法将从缓存中装载文档。这与用户单击浏览器的刷新按钮的效果是完全一样的。如果把该方法的参数设置为 true,那么无论文档的最后修改日期是什么,它都会绕过缓存,从服务器上重新下载该文档。这与用户在单击浏览器的刷新按钮时按住 Shift 健的效果是完全一样:

window.location.reload(true);

replace() 方法不会在 History 对象中生成一个新的记录。当使用该方法时,新的 URL 将覆盖 History 对象中的当前记录。用法为:

window.location.replace('http://example.com/');

通过 location 的属性与方法,我们可以做很多事情,详情可以查看 MDN