• HTML5的Histroy API


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


    Internet Explorer

    不支持

    Firefox

    4.0+

    Safari

    5.0+

    Google Chrome

    8.0+

    Opera

    不支持

    比较典型的是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/

    image

    image 

    这样即使我刷新页面,所有以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 {
    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”,代码有参阅人人网前台脚本(一时好奇就右击源码大致扫了一下)

  • 相关阅读:
    电源设计考虑的问题
    板级隔离电源
    浪涌特性
    LED
    电荷泵
    ps抠图
    cadence pcb 导入logo
    allegro pcb 设置快捷键
    【成长】今天,我也是个面试官(BIOS面试)
    【成长】---一枚研发狗的自我认知历程
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/2070235.html
Copyright © 2020-2023  润新知