前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不使用定时器实现的onhashchange

不使用定时器实现的onhashchange

作者头像
meteoric
发布2019-02-25 17:13:37
6220
发布2019-02-25 17:13:37
举报
文章被收录于专栏:游戏杂谈游戏杂谈

之前看sparks345 写的《不采用interval方式模仿onHashChange

后来自己又折腾了一把,完整的源码总共大小是1.66KB(2K不到)

支持:FF3.0+、IE6+、Chrome

image
image

主流的浏览器(IE6、IE7除外),基本上都支持onhashchange事件,而IE8也将支持。只有IE6、IE7不支持,而使用这两个浏览器的用户还是占有很大的一部分份额。

网上流传的实现onhashchange方法基本上都采用setInterval来跑,这样做:

第一:不切换也要去检测一次hash,总觉得别扭;

第二:点击过快的时候容易出bug(曾经耿耿于怀这个)

既然外面的轮子都不好用,还就自己造一个吧~

其实造也不难,因需要专门针对ie做一些处理就好了。页面放个iframe,然后然后iframe里面的内容,比如加个表单元素input并监听其onload事件,然后回调。

说明一下:这个方法不是我最先想到的,是我不经意见研究某站点的代码发现的,在这里先致谢一下。

HistoryManager.js的源码:

代码语言:javascript
复制
1: function HistoryManager() {

       2:     this.listener = null;

       3:     this.adapterIframe = null;

       4:     this._initialize();

       5: }

       6:  

       7: ~(function() {

       8:     var flag = false,

       9:         isIE = !!window.ActiveXObject && /msie (\d)/i.test(navigator.userAgent) ? RegExp['$1'] : false,

      10:         $pointer = this;

      11:     

      12:     this.makeIEHistory = function(url) {

      13:         if (!url) {

      14:             return ;

      15:         }

      16:         

      17:         var frameDoc = $pointer.adapterIframe.contentWindow.document;

      18:         

      19:         frameDoc.open();

      20:         frameDoc.write([

      21:             "<html>",

      22:                 "<head>",

      23:                     "<script type='text/javascript'>",

      24:                         "function pageLoaded() {",

      25:                             "try {top.window.historyManager.fireOnHashChange(\""+url+"\");} catch(ex) {}",

      26:                         "}",

      27:                     "</script>",

      28:                 "</head>",

      29:                 "<body onload='pageLoaded();'>",

      30:                     "<input type='value' value='"+url+"' id='history'/>",

      31:                 "</body>",

      32:             "</html>"

      33:         ].join(""));

      34:         frameDoc.title = document.title;

      35:         frameDoc.close();

      36:     }

      37:  

      38:     this.fireOnHashChange = function(url) {

      39:         location.hash = "#" + url.replace(/^#/, "");

      40:         

      41:         if (window.onhashchange) {

      42:             window.onhashchange();

      43:         }

      44:     }

      45:  

      46:     this.add = function(url) {

      47:         flag = true;

      48:  

      49:         if (isIE && isIE < 8) {

      50:             $pointer.makeIEHistory(url);

      51:         } else {

      52:             location.hash = "#" + url;

      53:         }

      54:     }

      55:  

      56:     this.fire = function(url) {

      57:         if (!url) {

      58:             url = document.location.hash.slice(1);

      59:         }

      60:  

      61:         $pointer.listener(url);

      62:     }

      63:  

      64:     this.addListener = function(fn) {

      65:         $pointer.listener = typeof fn === 'function' ? fn : function() {};

      66:     }

      67:  

      68:     this._initialize = function() {

      69:         if (isIE && isIE < 8) {

      70:             $pointer.adapterIframe = document.getElementById("HISTORY_ADAPTER");

      71:             $pointer.makeIEHistory();

      72:         }

      73:  

      74:         window.onhashchange = function() {

      75:             if (flag) {

      76:                 flag = false;

      77:                 return ;

      78:             }

      79:  

      80:             $pointer.fire();

      81:         }

      82:     }

      83:  

      84: }).call(HistoryManager.prototype);
代码语言:javascript
复制

使用方法,初始化一个实例,然后设置监听器,等待点击浏览器的“前进”、“后退”回调便可。

image
image
image
image

运行示例代码(初次加载可能无法下载脚本,刷新即可~):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>ajax历史记录</title> <meta name="generator" content="editplus" /> <meta name="author" content="" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <style type="text/css"> a {display:inline-block; margin-right:10px;} #clickHistory {border:1px solid #406c99; padding:15px; margin-top:10px; width:600px;} </style> </head> <body> <!--[if IE]><iframe id="HISTORY_ADAPTER" src="ajaxhistory.html" style="display:none"></iframe><![endif]--> <a href="#/1111/kk.html">Test1</a><a href="#/2222/kk.html">Test2</a><a href="#/3333/kk.html">Test3</a> <div id="clickHistory">I am the #1 ajax container..</div> <span id="preserve157d83c800624b7cb65a76bef93c4808" class="wlWriterPreserve"></span> <span id="preserve8682e3b47ba64be5b18f76d0a35a767d" class="wlWriterPreserve"></span> </body> </html> 预览代码

测试用的HTML源代码:

代码语言:javascript
复制
1: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

       2: <html>

       3:  <head>

       4:   <title>ajax历史记录</title>

       5:   <meta name="generator" content="editplus" />

       6:   <meta name="author" content="" />

       7:   <meta name="keywords" content="" />

       8:   <meta name="description" content="" />

       9:   <meta http-equiv="content-type" content="text/html;charset=utf-8">

      10:   <style type="text/css">

      11:     a {display:inline-block; margin-right:10px;}

      12:     #clickHistory {border:1px solid #406c99; padding:15px; margin-top:10px; width:600px;}

      13:   </style>

      14:  </head>

      15:  

      16:  <body>

      17:  

      18:     <!--[if IE]><iframe id="HISTORY_ADAPTER" src="ajaxhistory.html" style="display:none"></iframe><![endif]-->

      19:   <a href="#/1111/kk.html">Test1</a><a href="#/2222/kk.html">Test2</a><a href="#/3333/kk.html">Test3</a>

      20:  

      21: <div id="clickHistory">I am the #1 ajax container..</div>

      22:  

      23:   <script type="text/javascript" src="http://files.cnblogs.com/meteoric_cry/historyFrame.js"></script>   1:     2:   <script type="text/javascript">   3:     var historyManager = new HistoryManager();   4:     5:     historyManager.addListener(function() {   6:         var url = arguments[0];   7:     8:         alert("当前的改变后的URL:" + url);   9:           10:         setHashHistory(url);  11:     });  12:    13:     document.onclick = function(ev) {  14:         ev = ev || window.event;  15:         var elem = ev.srcElement || ev.target;  16:    17:         if (elem.tagName && elem.tagName.toLowerCase() == "a") {  18:             if (ev.preventDefault) {  19:                 ev.preventDefault();      20:             } else {  21:                 ev.returnValue = false;  22:             }  23:               24:             var href = elem.getAttribute("href", 2);  25:             historyManager.add(href);  26:    27:             setHashHistory(href);  28:         }  29:     }  30:    31:     function setHashHistory(_url) {  32:         var tid = _url.replace(/[^\/]?\/(\d+)\/(.*)/, "$1");  33:         var colorConfig = {  34:             '1111' : '#2B6088',  35:             '2222' : '#FD1B15',  36:             '3333' : '#FF6D06'  37:         }  38:           39:         var elem = document.getElementById("clickHistory");  40:         var html = elem.innerText || elem.contextText;  41:    42:         elem.innerHTML = html.replace(/\#(\d+)\s/, "#" + tid + " ");  43:         elem.style.backgroundColor = colorConfig[tid];  44:     }      45:   </script>

      24:  </body>

      25: </html>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-01-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档