使用 HTML5 History 新特性增强 Ajax 的体验(转)

一. 场景再现

如大家熟知,Ajax 可以实现页面的无刷新操作,但会造成两个与普通页面操作(有刷新地改变页面)有着明显差别的问题—— URL 没有修改以及无法使用前进、后退按钮。例如常见的 Ajax 分页,在第一页点击第二页的链接,Ajax 分页完成后浏览器地址栏上显示的 URL 依然是第一页的 URL,使用后退按钮也无法回到第一页。url 的改变代表一个标识,在传统的网页体验中,内容的变更伴随 url 的改变,url 的改变、前进和后退按钮三者之间更加形成一种独特的导航体验,而 Ajax 破坏了这种体验难免会对用户造成不便。

当然,很早之前,机智的前端工程师们已经想好了解决办法,最为常见的,就是使用 hash ——在 URL 结尾添加形如"#xxx" 的标识,然后用 onhashchange 等方式监听 hash 值变化作出相应处理。

很麻烦?是的,因此,HTML5 History 中新增了几个可以优雅地解决这些问题的特性!

二. HTML5 History 的新特性

History 对象从 HTML4 开始引入,HTML5 中增加了 pushState, replaceState 两个方法,和 popstate 事件。下面作一些简单的介绍。

1. pushState()方法

pushState() 的作用是往历史记录的堆栈中压入一条记录,该方法有三个参数:

state object —— 一个对象,用于保存状态信息,当 popstate 事件被触发时,popstate 事件对象的 state 属性会包含相应的 state object 的拷贝。state object 的容量很小(Firefox 中强制为 640k),如果需要储存较大的数据,建议使用 localStorage 或 sessionStorage。

title —— 即被压入的历史记录的页面的标题,该属性暂时被所有浏览器忽略,实际开发时可以填空字符或一个简短的标题。

url —— 新的历史记录的地址,可以是相对路径或绝对路径,若为相对路径则以当前 url 为基址。

2. replaceState()方法

replaceState() 方法与 pushState() 方法类似,参数与 pushState() 也相同,但 replaceState() 方法会修改当前的历史记录而并非创建新的记录,因此在需要更新当前历史记录的 state object 或 URL 时,使用该方法会更加合适。

3. popstate 事件

popstate 事件会在激活的历史记录发生变化(如前进、后退、调用 pushState 或 replaceState 方法)时触发在 window 对象上。如上面所描述,如果被激活的历史记录由 pushState 创建或是被 replaceState 修改,则 popstate 事件的状态属性将包含相应的 state object 的拷贝,开发者可以在 popstate 的回调中调用这些之前保存在 state object 中的信息。

值得注意的是,Chrome 会在打开页面(包括第一次打开页面)以及页面刷新时产生 popstate 事件而 Firefox 则不会,这会为开发带来一些麻烦,但下面会给出解决方案。

4. 浏览器兼容

特性 Chrome Firefox (Gecko) Internet Explorer Opera Safari
pushState, replaceState 5 4.0 (2.0) 10 11.50 5.0
history.state 18 4.0 (2.0) 10 11.50 6.0

三. 使用 History 的新特性增强 Ajax 体验

这里说的增强体验,实质就是要解决文章开头提到的两个问题 —— Ajax 翻页时不会修改 URL 以及前进、后退功能无效。

看了上面的方法,相信大家已经能想到基本的解决思路,无非就是在 Ajax 需求产生时 pushState 一条记录到历史记录中,然后在 popstate 的回调函数中作出相应的处理。当然,要想实际获得比较好的体验,要做的内容还是比较复杂的。下面以 Ajax 分页为例,提供一个完整思路:

  • 每次使用 Ajax 获取新页面后,使用 pushState() 把新页面的 url 压入历史记录栈顶。
  • 监听 popstate 事件,当用户前进或后退时在回调中根据前进或后退后的 URL 重新使用 Ajax 获取页面内容,实现 Ajax 前进与后退。
  • Chrome 在打开页面以及刷新页面后会产生 popstate 事件,导致多余的 Ajax 请求,因此需要 popstate 中利用 url 作为判断用户是否在点击前进或后退功能,抑或是打开、刷新页面,若为前进或后退才触发 Ajax 获取相应内容。

基本代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

// 定义 Ajax 获取分页方法,这里不列出具体内容

function turnPage(url){

    // ...

}

// 定义 popstate 的回调

if( history.pushState ){ // 判断浏览器是否支持 pushState

    // currentState 用于记录 popstate 产生前的页面 url,页面加载时初始化 currentState 为当前链接

    var currentState = window.location.href;

    window.addEventListener(‘popstate‘, function(event){

        

        // _currentUrl 用于记录 popstate 产生时的页面 url

        var _currentUrl = window.location.href;

        

        /* 判断 currentState 和 _currentUrl 是否相同,

         * 若相同则表明这个 popstate 产生前后页面 url 没有变化,

         * 即页面是第一次加载页面或者被刷新,无需触发新的 Ajax 请求,

         * 若不同则表明 url 已改变,这是触发 Ajax 获取内容

         */

        if( currentState != _currentUrl ){

        

            console.log(‘获取新分页‘);

                

            turnPage(_currentUrl); // 根据当前 url 重新获取分页内容

            

            currentState = _currentUrl; // 更新 currentState

        

        }

  

    });

}

// 绑定点击分页产生 Ajax 请求

// 点击分页链接,获取 url 为 currentLink,产生一次 Ajax 请求

turnPage(currentLink);

// 调用 pushState() 压入新记录

if( history.pushState ){ // 判断浏览器是否支持 pushState

    // 往历史记录中压入新记录,浏览器的地址栏上的 url 同时会被修改为新 url

    history.pushState(null, document.title, currentLink);

        

    currentState = window.location.href; // 分页时更新 currentState 为当前 url

}

本站已经根据上面的思路进行了 Ajax 分页的增强,具体的情况如下:

打开页面,url 显示为首页的 url

点击第二页链接,触发 Ajax 分页,在 Ajax 中调用 pushState() ,可以看到,url 已经被修改为第二页的 url

点击后退按钮,url 地址变为第一页,再在 popstate 的回调中触发 Ajax 获取第一页的内容。

这样,就做到了既吸收了局部刷新页面的好处同时保留传统的 url 导航体验。而对于不支持 pushState 的浏览器,可以使用渐进增强设计忽略这些浏览器,毕竟这是一个增强体验的功能;当然如果必须照顾那些浏览器,也可以采用 hash 的方案代替。

四. 现有的解决方案

如果需要直接的解决方案,可以参考这个封装好并且实现了跨浏览器兼容的库 —— History.js

本文由 Kayo Lee 发表,本文链接:http://kayosite.com/html5-history-improve-ajax.html

时间: 2025-01-16 02:12:17

使用 HTML5 History 新特性增强 Ajax 的体验(转)的相关文章

HTML5 history新特性pushState、replaceState

从HTML5开始,我们可以开始操作这个历史记录堆栈. DOM中的window对象通过window.history方法提供了对浏览器历史记录的读取,让你可以在用户的访问记录中前进和后退. 1.History 使用back(),forward(),和go()方法可以在用户的历史记录中前进和后退 前进和后退 后退: window.history.back(); 这个方法会像用户点击了浏览器工具栏上的返回键一样. 同样的,也可以用以下方法产生用户前进行为: window.history.forward(

HTML5的新特性和优缺点

HTML5的新特性 1. 语义特性(Class:Semantic) HTML5赋予网页更好的意义和结构.更加丰富的标签将随着对RDFa的微数据与微格式等方面的支 持,构建对程序.对用户都更有价值的数据驱动的Web. 2. 本地存储特性(Class: OFFLINE & STORAGE) 基于HTML5开发的网页APP拥有更短的启动时间,更快的联网速度,这些全得益 于HTML5 APP Cache,以及本地存储功能.Indexed DB(html5本地存储最重要 的技术之一)和API说明文档. 3

jdk1.5出现的新特性---->增强for循环

package cn.itcast.jdk15; import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.Set; /*jdk1.5出现的新特性---->增强for循环 增强for循环的作用: 简化迭代器的书写格式.(注意:增强for循环的底层还是使用了迭代器遍历.) 增强for循环的适用范围: 如果是实现了Iterable接

HTML5 基本新特性总概

html5 什么是html5:html5是下一代的HTML,将成为html.xhtml以及HTML DOM的新标准. 参考: HTML5的十大新特性 前端面试必备之html5的新特性 HTML5 1.语义化元素 1.1结构元素 标签 描述 article 表示与上下文不相关的独立内容区域 aside 定义页面的侧边栏区域 header 定义页面头部区域 hgroup 用于对页面中一个区域或整个页面的标题进行组合 footer 定义页面的底部区域 section 定义文档中的节段 nav 定义页面

使用Modernizr探测HTML5/CSS3新特性

HTML5, CSS3以及相关技术(例如canvas和web sockets)带来了非常有用的特性,可以让我们的web程序提升一个新的level.这些新技术允许我们只用HTML,CSS和JavaScript 就可以构建包括在平板和移动设备上能够运行的多样化表单页面.HTML5虽然提供了很多新特性,但是如果我们不考虑旧版本的浏览器就是用这些新技术也不太 现实,老版本浏览器已经使用了很多年,我们依然需要考虑这些版本的兼容性问题.本文要解决的问题就是:在我们使用HTML5/CSS3技术的时候,如何更

HTML5的新特性(面试必备)

面试前端的时候,有可能面试官会问你,让你谈谈对HTML5的认识.在教材上有关于HTML5新特性的概述,我觉得有必要整理一下,可以让自己对HTML5有一个比较全面的认知. HTML5不仅仅是HTML规范的当前最新版本,也代表了一系列Web相关技术的总称,其中最重要的3项技术就是HTML5核心规范.CSS3(层叠样式表的最新版本)和JavaScript(一种脚本语言,用于增强网页的动态功能). 它的新特性: 1.进化而非颠覆 试想,如果HTML5否定了之前的HTML文档,各种大大小小的网站都要重写,

HTML5的新特性及技巧分享总结

原文链接:http://www.aseoe.com/show-10-645-1.html?utm_source=tuicool&utm_medium=referral 1. 新的Doctype 尽管使用<!DOCTYPE html>,即使浏览器不懂这句话也会按照标准模式去渲染 所有浏览器都支持 <!DOCTYPE> 声明. <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令. 在 HTML 4.

HTML5的新特性

HTML5 中的一些有趣的新特性: 用于绘画的 canvas 元素 用于媒介回放的 video 和 audio 元素 对本地离线存储的更好的支持 新的特殊内容元素,比如 article.footer.header.nav.section 新的表单控件,比如 calendar.date.time.email.url.search 一.html5视频: 直到现在,仍然不存在一项旨在网页上显示视频的标准. 今天,大多数视频是通过插件(比如 Flash)来显示的.然而,并非所有浏览器都拥有同样的插件.

html5标准新特性及其使用技巧

运用html5新特性,首先需要声明头文件,其实浏览器不认识头也会照最新标准渲染.声明后网站结构如下:1 <!DOCTYPE html> <html><head> <!--html lang="zh-cmn-Hans"--> <meta charset="UTF-8"> <!--<link rel="stylesheet"type="text/css"hre