文档章节

HTML5无刷新修改URL:利用 History API 无刷新更改地址栏

周进
 周进
发布于 2015/12/21 14:27
字数 1199
阅读 1323
收藏 14

HTML5 新增的历史记录 API 可以实现无刷新更改地址栏链接,配合 AJAX 可以做到无刷新跳转。

简单来说:假设当前页面为renfei.org/,那么执行下面的 JavaScript 语句:

window.history.pushState(null, null, "/profile/");

之后,地址栏的地址就会变成renfei.org/profile/,但同时浏览器不会刷新页面,甚至不会检测目标页面是否存在。

pushState 方法

上面的语句实际上用到了 HTML5 的历史记录 API。这套 API 提供一种「人为操纵」浏览器历史记录的方法。

浏览器历史记录可以看作一个「栈」。栈是一种后进先出的结构,可以把它想象成一摞盘子,用户每点开一个新网页,都会在上面加一个新盘子,叫「入栈」。用户每次点击「后退」按钮都会取走最上面的那个盘子,叫做「出栈」。而每次浏览器显示的自然是最顶端的盘子的内容。

执行pushState函数之后,会往浏览器的历史记录中添加一条新记录,同时改变地址栏的地址内容。它可以接收三个参数,按顺序分别为:

  1. 一个对象或者字符串,用于描述新记录的一些特性。这个参数会被一并添加到历史记录中,以供以后使用。这个参数是开发者根据自己的需要自由给出的。

  2. 一个字符串,代表新页面的标题。当前基本上所有浏览器都会忽略这个参数。

  3. 一个字符串,代表新页面的相对地址。

例如,我们可以这样写:

var state = {
    id: 2,
    name: "profile"
};
window.history.pushState(state, "My Profile", "/profile/");

popstate 事件

当用户点击浏览器的「前进」、「后退」按钮时,就会触发popstate事件。你可以监听这一事件,从而作出反应。

window.addEventListener("popstate", function(e) {
    var state = e.state;     // do something... 
});

这里e.state就是当初pushState时传入的第一个参数。例如,在我们的例子中,有:

e.state.id == 2;
e.state.name == "profile";

replaceState 方法

有时,你希望不添加一个新记录,而是替换当前的记录(比如对网站的 landing page),则可以使用replaceState方法。这个方法和pushState的参数完全一样。

应用:全站 AJAX,并使浏览器能够抓取 AJAX 页面

这个可以干啥用?一个比较常用的场景就是,配合 AJAX。

假设一个页面左侧是若干导航链接,右侧是内容,同时导航时只有右侧的内容需要更新,那么刷新整个页面无疑是浪费的。这时我们可以使用 AJAX 来拉取右面的数据。但是如果仅仅这样,地址栏是不会改变的,用户无法前进、后退,也无法收藏当前页面或者把当前页面分享给他人;搜索引擎抓取也有困难。这时,就可以使用 HTML5 的 History API 来解决这个问题。

思路:首先绑定click事件。当用户点击一个链接时,通过preventDefault函数防止默认的行为(页面跳转),同时读取链接的地址(如果有 jQuery,可以写成$(this).attr('href')),把这个地址通过pushState塞入浏览器历史记录中,再利用 AJAX 技术拉取(如果有 jQuery,可以使用$.get方法)这个地址中真正的内容,同时替换当前网页的内容。

为了处理用户前进、后退,我们监听popstate事件。当用户点击前进或后退按钮时,浏览器地址自动被转换成相应的地址,同时popstate事件发生。在事件处理函数中,我们根据当前的地址抓取相应的内容,然后利用 AJAX 拉取这个地址的真正内容,呈现,即可。

最后,整个过程是不会改变页面标题的,可以通过直接对document.title赋值来更改页面标题。

其他说明

URL 的限制

为了安全考虑,新 URL 必须和当前 URL 在同一个域名下。例如,你不能把地址改成 Google 的首页。否则不怀好心的人就可以把地址改成网银等关键网站的地址,来迷惑用户了。

但是,URL 允许使用 query string 的形式。例如:

window.history.pushState(null, null, "?id=1");

在某些情况下可能比较方便。

浏览器兼容性

根据 MDN 提供的信息,IE 10, Chrome 5, Firefox 4, Safari 5 开始支持这个特性。Fallback 可以采用替换 hash 的方法。另外,History.js 库也提供了对老版本浏览器的 history API 支持(同样是利用替换 hash)。为了搜索引擎收录,可能需要使用#!表示法。


本文转载自:https://www.renfei.org/blog/html5-introduction-3-history-api.html

周进
粉丝 16
博文 35
码字总数 5679
作品 0
成都
CTO(技术副总裁)
私信 提问
加载中

评论(1)

MGL_TECH
MGL_TECH
mark
Vue-router中hash与history的区别

Vue为了构建 SPA, 需要引入前端路由系统Vue-Router。前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求。 为了达到这一目的,利用浏览器的特性, Vue-Router提供了以下两种路由模...

老菜鸟0217
01/08
81
0
利用HTML5的History API实现无刷新跳转页面初探

HTML4中的History API history这个东西大家应该都不陌生,我们经常使用history.back(-1)来实现后退功能,具体的属性和方法如下: 属性 length 历史的项数。JavaScript 所能管到的历史被限制在...

easonjim
2016/12/23
0
0
【深入吧,HTML 5】 性能 & 集成 —— History API

博客 有更多精品文章哟。 前言 在深入了解 History API 之前,我们需要讨论一下前端路由;路由指的是通过不同 URL 展示不同页面或者内容的功能,这个概念最初是由后端提出的,因此,在传统的...

晨风明悟
02/01
0
0
H5页面监听Android物理返回键

Android物理返回键的点击事件,一般webview的默认行为是 ,但是在实际需求场景下,简单的页面回退并不能满足需求,所以需要H5页面监听Android物理返回键从而自定义处理方法。 本方案的代码都...

hujiao
2018/12/11
0
0
Angularjs $location html5mode浅析

关于HTML5 history API 参考资料:http://diveintohtml5.info/history.html 参考资料为英文,内容较为简单,周末会做简单翻译,方便英语吃力的童鞋。 H5之前,一个URL对应一个页面,无论以何...

怀疑真爱的流浪者jason
09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark sql的批处理物理计划BatchScanExec

BatchScanExec是batch类的物理计划,对应的逻辑计划是DataSourceV2Relation,是Datasource。 它的入参是Scan类,Scan类有两个重要方法,一个获取分区列表信息;另一个方法获取读取器工厂。 ...

守望者之父
28分钟前
10
0
for循环与while循环

循环结构三要素 a. 初始值 b. 循环条件 c. 改变条件 for循环 声明格式 for(表达式1;表达式2;表达式3){ 循环体语句 } 表达式1:用来循环的变量初始值。(开始值) 表达式2:用来判断循环的条件。...

Lenat
33分钟前
11
0
进程描述符和内存描述符、进程栈、线程栈、内核栈

进程描述符 task_struct 线程创建的时候,加上了 CLONE_VM 标记,这样 线程的内存描述符 将直接指向 父进程的内存描述符。 内存描述符mm_struct 进程栈:stack 线程栈:使用mmap系统调用分配...

SibylY
35分钟前
12
0
Mybatis之TypeHandler

mybatis-3.4.6.release. TypeHandler在mybatis中是个重要的组件,对statement设置参数还是从Resultset中取值,都会用到它。 List-1 public interface TypeHandler<T> { void setParame......

克虏伯
46分钟前
11
0
js—String的一些方法

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> var str="Hello boy" /** * 在底......

zhengzhixiang
58分钟前
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部