作者:zccst

旧版: 
forword() 
backword() 
go(number)

HTML5中新增了 
onhashchange  浏览器兼容性较好,用得较多 
pushState / replaceState / onpopState

一、onhashchange 
hashchange事件在当前页面URL中的hash值发生改变时触发 (查看location.hash).

区别: 
通过window.onpopstate来监听url的变化,但会忽略URL的hash部分。

结论:两者恰恰互补,各有分工。

  1. if ("onhashchange" in window) {
  2. alert("该浏览器支持hashchange事件!");
  3. }
  4. function locationHashChanged() {
  5. if (location.hash === "#somecoolfeature") {
  6. somecoolfeature();
  7. }
  8. }
  9. window.onhashchange = locationHashChanged;

hashchange 事件对象有下面两个属性 
newURL DOMString 当前页面新的URL 
oldURL DOMString 当前页面旧的URL

二、pushState / replaceState / onpopState

(通俗易懂版) 
HTML5的新API扩展了window.history,使历史记录点更加开放了。可以存储当前历史记录点、替换当前历史记录点、监听历史记录点,下面逐一简要说明一下。

1、存储当前历史记录点

存储的方式类似于数组的入栈(Array.push()),在window.history里新增一个历史记录点,例如:

// 当前的url为:http://qianduanblog.com/index.html 
var json={time:new Date().getTime()}; 
// @状态对象:记录历史记录点的额外对象,可以为空 
// @页面标题:目前所有浏览器都不支持 
// @可选的url:浏览器不会检查url是否存在,只改变url,url必须同域,不能跨域 
window.history.pushState(json,"","http://qianduanblog.com/post-1.html"); 
执行了pushState方法后,页面的url地址为http://qianduanblog.com/post-1.html。

2、替换当前历史记录点

window.history.replaceState和window.history.pushState类似,不同之处在于replaceState不会在window.history里新增历史记录点,其效果类似于window.location.replace(url),都是不会在历史记录点里新增一个记录点的。当你为了响应用户的某些操作,而要更新当前历史记录条目的状态对象或URL时,使用replaceState()方法会特别合适。

3、监听历史记录点

监听历史记录点,直观的可认为是监听URL的变化,但会忽略URL的hash部分,监听URL的hash部分,HTML5有新的API为onhashchange,我的博客里也有说到该方法和跨浏览器的兼容解决方案。可以通过window.onpopstate来监听url的变化,并且可以获取存储在该历史记录点的状态对象,也就是上文说到的json对象,如:

// 当前的url为:http://qianduanblog.com/post-1.html 
window.onpopstate=function() 

// 获得存储在该历史记录点的json对象 
var json=window.history.state; 
// 点击一次回退到:http://qianduanblog.com/index.html 
// 获得的json为null 
// 再点击一次前进到:http://qianduanblog.com/post-1.html 
// 获得json为{time:1369647895656} 

值得注意的是:javascript脚本执行window.history.pushState和window.history.replaceState不会触发onpopstate事件。

(文绉绉版) 
HTML5引进了history.pushState()方法和history.replaceState()方法,它们允许你逐条地添加和修改历史记录条目。这些方法可以协同window.onpopstate事件一起工作。

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

新的URL可以是任意的同源URL,与此相反,使用window.location方法时,只有仅修改 hash 才能保证停留在相同的document中。 
根据个人需要来决定是否修改URL。相反,设置window.location='#foo',只有在当前hash值不是foo时才创建一条新历史记录。 
你可以在新的历史记录条目中添加抽象数据。如果使用基于hash的方法,你只能把相关数据转码成一个很短的字符串。 
注意pushState()方法永远不会触发hashchange事件,即便新的地址只变更了hash。

2,replaceState()方法 
history.replaceState()操作类似于history.pushState(),不同之处在于replaceState()方法会修改当前历史记录条目而并非创建新的条目。

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

3,popstate事件

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

举例: 
history.pushState 
菊花插一刀之意,用法举例: 
history.pushState({}, "页面标题", "xxx.html"); 
history.pushStatehistory.replaceState 
换把菊花刀之意,用法举例: 
history.replaceState(null, "页面标题", "xxx.html"); 
window.onpopstate 
在菊花刀拔插的时候……,用法举例: 
window.addEventListener("popstate", function() { 
    var currentState = history.state; 
    /* 
     * 该干嘛干嘛 
    */
});

完整实例: 
http://www.zhangxinxu.com/wordpress/2013/06/html5-history-api-pushstate-replacestate-ajax/

策略如下: 
每次手动点击左侧的菜单,我将Ajax地址的查询内容(?后面的)附在demo HTML页面地址后面,使用history.pushState塞到浏览器历史中。 
浏览器的前进与后退,会触发window.onpopstate事件,通过绑定popstate事件,就可以根据当前URL地址中的查询内容让对应的菜单执行Ajax载入,实现Ajax的前进与后退效果。 
页面首次载入的时候,如果没有查询地址、或查询地址不匹配,则使用第一个菜单的Ajax地址的查询内容,并使用history.replaceState更改当前的浏览器历史,然后触发Ajax操作。

window.history的更多相关文章

  1. safari 浏览器window.history.go(-1)运行无效解决办法

    这几天做了几个手机端app的wap页面,做完之后发现一个问题,那就是ios系统下的safari浏览器不支持window.history.go(-1)..无语... 解决方法很简单!加上return f ...

  2. javascript:window.history.go(-1)

    history是你浏览过的网页的url(简单的说就是网址)的集合,也就是你的浏览器里的那个历史记录.它在js里是一个内置对象,就跟document一样,它有自己的方法,go就是其中一个. 这个方法的参 ...

  3. window.history 和 DWZ 框架

    DWZ框架的ajax请求返回的一般都是一个HTML片段,整个页面是由一个个HTML片段组成的,可以由TAB切换其内容,但是只有一个body和HEAD,一般head 和 菜单栏是不会动的. 今天遇到一个 ...

  4. window.history.pushState与ajax实现无刷新更新页面url

    ajax能无刷新更新数据,但是不能更新url HTML5的新API: window.history.pushState, window.history.replaceState 用户操作history ...

  5. javascript宿主对象之window.history

    window.historys属性允许我们操作同一个浏览器回话中的已访问页面,例如我们可以看到在这之前我们浏览页面的数量: window.history.length 由于隐私保护,我们无法获取这些页 ...

  6. 由window.history.back()引发的问题

    由window.history.back()引发的问题 编写人:CC阿爸 2015-1-30 今天在这里,我想与大家一起分享由windows.history.back()引发的问题,笔者在实际开发当中 ...

  7. 使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. 返回页面,主页面不刷新window.history.go(-1),主页面刷新window.location.go(-1)

    返回上一页,不刷新 window.history.go(-1) 返回上一页,刷新 window.location.go(-1)

  9. 关于window.history.back()后退问题

    Windows下的window.history.back()后退后返回的不仅仅是前一个页而是前一个页的状态.假设一个页我改动了3次那必须后退3次才干回到前一个页.并且数据库中删除的数据依旧显示在上面感 ...

随机推荐

  1. 官方 Animator 例子解析 Animator.MatchTarget

    一.官方的解释 Animator.MatchTargetSwitch to Manual ); Parameters matchPosition The position we want the bo ...

  2. Network Saboteur(Rand版)

    poj2531:http://poj.org/problem?id=2531 题意:给你一个图,图中点之间会有边权,现在问题是把图分成两部分,使得两部分之间边权之和最大.题解:随机算法 #includ ...

  3. JsRender系列demo(4)-if else

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. 重写equals()方法时,需要同时重写hashCode()方法

    package com.wangzhu.map; import java.util.HashMap; /** * hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,<br/&g ...

  5. Project Euler 93:Arithmetic expressions 算术表达式

    Arithmetic expressions By using each of the digits from the set, {1, 2, 3, 4}, exactly once, and mak ...

  6. 【mysql的编程专题①】流程控制与其他语法

    流程控制与内置函数,一般用在select的field字段上,或者用在函数,存储过程,触发器中; 如果用在select上就会随着query出来的row来隐式迭代; 注释与语句结束符 语句结束符 默认有两 ...

  7. PHP程序员的40点陋习

    1.不写注释 2.不使用可以提高生产效率的IDE工具 3.不使用版本控制 4.不按照编程规范写代码 5.不使用统一的方法 6.编码前不去思考和计划 7.在执行sql前不执行编码和安全检测 8.不使用测 ...

  8. VS2012 开发SharePoint 2013 声明式workflow action(activity)之 HelloWorld

    本文讲述VS2012 开发SharePoint 2013 声明式workflow action 之 HelloWorld. 使用VS2012开发客户化的workflow action是SharePoi ...

  9. Android Material Design-TabLayout的使用

    TabLayout 位于 android.support.design.widget.TabLayout. 一般与 ViewPager 结合在一起使用.以前有开源库 viewpagerindicato ...

  10. 自动化:Appium运行成功,取得一个小的胜利

    看过乙醇大神的博文,然后又看了一些大神的博文,自己陆陆续续的折腾了一个月,今天上午的时候,appium终于跑起来了.纪念下,在自动化路上取得的一个小胜利 Appium版本:1.2 Python版本:2 ...