HTML5的Histroy API

History API在各浏览器下的支持情况:

不支持

4.0+

5.0+

8.0+

不支持

比较典型的是GitHub,在点击代码文件夹和文件时,会发现它的url地址栏变换了、标题栏变化了、前进后退按钮也变化了(跟新开了一个新页面感觉一样),但体验起来很平滑(外层框架的内容没有重新加载,例如:登录信息、是否关注主人等),然后是ajax载入新内容。

history在HTML4的时代里,有如下几个方法和属性,应该很熟悉:

length、back()、forward()、go([delta])

在HTML5中又添加了两个方法:

pushState(data, title[,url])、replaceStage(data, this [,url])

需要注意的是在使用replaceStage,传入的url必须和当前页的协议、所在域完全相同(即使不同的子域都不行),否则会提示安全错误。

更多内容可以参考:

http://diveintohtml5.org/history.html

http://dev.w3.org/html5/spec-author-view/history.html

如果想在兼容其它老浏览器,可以使用History.js

这里写了一个测试实例,参考至:http://html5demos.com/history

因为URL变换了,而在刷新的时候页面又不能进行跳转,此时需要在自己的web服务器上写一些规则了(我本机使用的是nginx),在server_name为meteoric.com的vhost中添加如下规则:

location ~ ^/history/.*$ {         rewrite ^/history/.*$ /html5/history/index.html last; }

页面访问路径是:http://meteoric.com/history/

这样即使我刷新页面,所有以history开头的请求,都将转至http://meteoric.com/history/index.html

/=======/

1、因为页面没有跳转,所以在点击链接的时候可以使用ajax请求并渲染数据(类似github的效果)

2、进页面,可以获取到当前URL,然后正则取出histroy其后的内容,判定加载哪一种资源

页面完整的HTML代码:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset=utf-8 /> 
<meta name="viewport" content="width=620" /> 
<title>HTML5__History API</title> 
  <style>
body { 
  font: normal 16px/20px "Helvetica Neue", Helvetica, sans-serif;
  background: rgb(237, 237, 236);
  margin: 0;
  margin-top: 40px;
  padding: 0;
}

section, header, footer {
  display: block;
}

#wrapper {
  width: 600px;
  margin: 0 auto;
  background-color: #fff;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  border-top: 1px solid #fff;
  padding-bottom: 76px;
}

h1 {
  padding-top: 10px;
}

h2 {
  font-size: 100%;
  font-style: italic;
}

header, article > *, footer > * {
  margin: 20px;
}

footer > * {
  margin: 20px;
  color: #999;
}

#status {
  padding: 5px;
  color: #fff;
  background: #ccc;
}

#status.fail {
  background: #c00;
}

#status.success {
  background: #0c0;
}

#status.offline {
  background: #c00;
}

#status.online {
  background: #0c0;
}

li {
  margin-bottom: 10px;
}

#examples {
  padding-left: 20px;
}
#examples li {
  list-style: square;
  padding: 0;
  margin: 0;
}
</style> 
 </head>

 <body>
 
 <section id="wrapper">
<article> 
  <p id="status">HTML5 History API not supported</p> 
  <p>最后一次触发的事件: <em><span id="lastevent">(none)</span></em></p> 
  <p>点击下面的链接进行测试,点击后页面的URL发生变化,但重新刷新后依旧停留于此页面。</p> 
  <p>可以使用浏览器原生的前进、后退按钮</p> 
  <ul id="examples"> 
    <li><a href="/history/first">first</a></li> 
    <li><a href="/history/second">second</a></li> 
    <li><a href="/history/third">third</a></li> 
    <li><a href="/history/fourth">fourth</a></li> 
  </ul> 
  <div id="output"></div> 
</article> 
</section>


<script>   1:     2:     3: var addEvent = (function () {   4:   if (document.addEventListener) {   5:     return function (el, type, fn) {   6:       if (el && el.nodeName || el === window) {   7:         el.addEventListener(type, fn, false);   8:       } else if (el && el.length) {   9:         for (var i = 0; i < el.length; i++) {  10:           addEvent(el[i], type, fn);  11:         }  12:       }  13:     };  14:   } else {  15:     return function (el, type, fn) {  16:       if (el && el.nodeName || el === window) {  17:         el.attachEvent('on' + type, function () { return fn.call(el, window.event); });  18:       } else if (el && el.length) {  19:         for (var i = 0; i < el.length; i++) {  20:           addEvent(el[i], type, fn);  21:         }  22:       }  23:     };  24:   }  25: })();  26:    27:    28:    29:    30: var $ = function (s) { return document.getElementById(s); },  31:     state = $('status'),  32:     lastevent = $('lastevent'),  33:     urlhistory = $('urlhistory'),  34:     examples = $('examples'),  35:     output = $('output'),  36:     template = '<p>URL: <strong>{url}</strong>, name: <strong>{name}</strong>, location: <strong>{location}</strong></p>',  37:     data = { // imagine these are ajax requests :)  38:       first : {  39:         name: "张三",  40:         location: "北京"  41:       },  42:       second: {  43:         name: "李四",  44:         location: "上海"  45:       },  46:       third: {  47:         name: "王五",  48:         location: "重庆"  49:       },  50:       fourth: {  51:         name: "小六",  52:         location: "江苏,南京"  53:       }  54:     };  55:    56: function reportEvent(event) {  57:   lastevent.innerHTML = event.type;  58: }  59:    60: function reportData(data) {  61:   output.innerHTML = template.replace(/(:?\{(.*?)\})/g, function (a,b,c) {  62:     return data[c];  63:   });  64: }  65:    66: //检测浏览器对此特性的支持情况  67: !(function() {  68:     if (typeof history.pushState === 'undefined') {  69:       state.className = '当前浏览器不支持HTML5 History API';  70:     } else {  71:       state.className = 'success';  72:       state.innerHTML = '当前浏览器支持HTML5 History API';  73:     }  74: })();  75:    76: addEvent(examples, 'click', function (event) {  77:   var title;  78:     79:   event.preventDefault();  80:   if (event.target.nodeName == 'A') {  81:     title = event.target.innerHTML;  82:     data[title].url = event.target.getAttribute('href'); // slightly hacky (the setting), using getAttribute to keep it short  83:     history.pushState(data[title], title, event.target.href);  84:     reportData(data[title]);  85:   }  86: });  87:    88: addEvent(window, 'popstate', function (event) {  89:   var data = event.state;  90:   reportEvent(event);  91:   reportData(event.state || { url: "unknown", name: "undefined", location: "undefined" });  92: });  93:    94: addEvent(window, 'hashchange', function (event) {  95:   reportEvent(event);  96: });  97:    98: addEvent(window, 'pageshow', function (event) {  99:   reportEvent(event); 100: }); 101:   102: addEvent(window, 'pagehide', function (event) { 103:   reportEvent(event); 104: }); 105:  </script>

 </body>
</html>

因为需要web服务器的支持,所以上述效果无法在blog中进行预览。需有兴趣,可搭建一个简单的环境进行测试~

如果有兴趣浏览兼容ie6+(无定时器)的history,可以阅读人人网前端开发人员的这篇文章:http://jingwei.li/blog/?p=183

之前我也写过一篇相关的文章:”不使用定时器实现的onhashchange”,代码有参阅人人网前台脚本(一时好奇就右击源码大致扫了一下)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Web 开发

Deploy WordPress On SAE

也没怎么刻意去选择,从各种cPanel主机,到VPS,再到AppFog等Pass,基本上都玩了一遍了。

10100
来自专栏Google Dart

AngularDart4.0 英雄之旅-教程-07路由 顶

如果该应用程序尚未运行,请启动该应用程序。 在进行更改时,请通过重新加载浏览器窗口来保持运行。

19330
来自专栏大数据钻研

前端开发面试题总结之——HTML

---- 相关知识点 web标准、 web语义化、 浏览器内核、 兼容性、 html5... 题目&答案 Doctype作用?严格模式与混杂模式如何区分?它们有...

37680
来自专栏地方网络工作室的专栏

Python3 初学实践案例(7)tkinter 入门 GUI 的密码生成程序

Python3 初学实践案例(7)tkinter 入门 GUI 的密码生成程序 前面我已经非常好的完成了 cli 的密码生成程序的编写 http://blog....

31180
来自专栏狮乐园

高级 Angular 组件模式 (7)

因为父组件会提供所有相关的 UI 元素(比如这里的 button),所以 toggle 组件的开发者可能无法满足组件使用者的一些附加需求,比如,在一个自定义的开...

18620
来自专栏BestSDK

一文读懂Xcode 9 所有更新:全新模拟器,兼容Swift低版本等

代码重构功能增强 这次 Xcode 9 对代码重构功能有较大的提升,首先是重命名功能,在编辑器中点击类名,然后选择 Refactor -> Rename: ?...

46470
来自专栏编程

Python2下载单张图片和爬取网页图片

昨天用Python2爬取了一首歌的热评和评论总数,今天用Python2来下载图片。 一、需求分析 1、知道图片的url地址,将图片下载到本地。 2、知道网页地址...

28990
来自专栏前端之路

–[New]Vue项目使用vw实现移动端适配教程

22830
来自专栏速成应用小程序开发平台

新手教程|速成应用教你如何制作搭建自己的微信小程序

微信小程序已经迈入了爆发阶段,很多中小企业和商户正在不断涌入这个市场。但是很多不懂技术不懂代码的小白却不知道去哪里制作微信小程序,现在就以可视化小程序开发工具「...

2.6K50
来自专栏韩东吉的Unity杂货铺

零基础入门 3: 窗口介绍(一)

前两篇介绍了Unity的环境布置,破解,平台切换。如果哪里有所遗忘可以翻看历史消息重新巩固下。

13830

扫码关注云+社区

领取腾讯云代金券