ajax实现浏览器前进后退-location.hash与模拟iframe
Aajx实现无数据刷新时,我们会遇到浏览器前进后退失效的问题以及URL不友好的问题。 实现方式有两种 1、支持onhashchange事件的,通过更新和读取location.hash的方式来实现 /* 因为Javascript对dom的操作是不持久化的,刷新后就恢复原状,而且也不保存历史记录,也就无法前进后退来查看历史了。但是可以采用“地址栏加hash”技术来解决。 */ 2、通过内嵌一个iframe来模拟实现页面的前进后退,通过iframe的onload事件来实现 /* 我可应很负责任的告诉你:ajax加载页面是无法实现浏览器前进和后退功能的, 因为你是直接通过jq 将当前页面的内容全给替换掉了,而页面并没有跳转。 不过不是所有事都是绝对的。告诉你一个比较笨但是有比较实用的方法。 就是通过iframe轻松解决问题。 首先,你的页面需要一个隐藏的iframe,且iframe的src对应的是一个任意的html,jsp都行。 当你ajax加载页面之前,用jq将当前的页面内容给加载到iframe中去,这个时候,你的iframe中的html元素,就是你当前页面的html元素没错把?这时候再加载你需要ajax加载的页面。注意,加载页面的时候千万不要把这个iframe给覆盖掉了。。。 再写一个键盘后退按键的js监控方法,当按下backspace的时候,将iframe的页面元素加载出来覆盖当前页面,在覆盖之前记得要把现在的页面元素覆盖到iframe中,因为你还有一个前进的操作 前进的操作也是大同小异,说白了就是父页面元素与iframe中的页面元素进行对换的操作 */ 具体代码如下,里面内嵌到的各个页面,自己建立同名文件即可。 <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <style type="text/css"> .tab { display: inline; } .tab a { color: #fff; background: #333; padding: 5px 10px; border-left: 1px solid #fff; } .tab .selected { color: red; background: #cecece; } .content { background: #cecece; width: 50%; margin-top: 5px; padding: 10px; } pre { border: 1px inset gray; height: 20em; } </style> </head> <body > <script type="text/javascript"> function Ajax (params) { if (params) { this.XMLHttp = params.XMLHttp; this.method = params.method; } this.onsuccess = null; this.responseType = 'text'; } Ajax.prototype = { getXMLHttp : function () { if (!this.XMLHttp) { if (window.XMLHttpRequest) { // code for IE7+,Firefox,Chrome,Opera,Safari return new XMLHttpRequest(); } else {// code for IE6,IE5 return new ActiveXObject("Microsoft.XMLHTTP"); } } return this.XMLHttp; }, request : function (url,data) { var self = this; try { var http = this.getXMLHttp(); //make a connection to the server ... specifying that you intend to make a GET request //to the server. Specifiy the page name and the URL parameters to send var param = ''; for (var item in data) { param += (item + '=' + data[item] + '&'); } url += ( (url.indexOf('?') != -1) ? '&' : '?' ) + param; var urlLen = url.length; if (url.substr(urlLen - 1,urlLen) == '&') { url = url.substr(0,urlLen - 1); } http.open(this.method,url); //assign a handler for the response http.onreadystatechange = function() { self.response(http); } //actually send the request to the server http.send(null); } catch (e) { alert(e.message); } }, get : function (url,data,type,onsuccess) { this.method = 'GET'; this.responseType = type || this.responseType; this.onsuccess = onsuccess; this.request(url,data); }, post : function (url,onsuccess) { this.method = 'POST'; this.responseType = type || this.responseType; this.onsuccess = onsuccess; this.request(url, response : function(http) { if (http.readyState == 4) { // 4 = "loaded" if (http.status == 200) { // 200 = OK this.onloadDone(http); } else { this.onerror('加载失败'); } } }, onloadDone : function(http) { // var data = http.responseText || http.responseXML; var data = this.responseType.toLowerCase() == 'xml' ? http.responseXML : http.responseText; this.onsuccess.call(this, onerror : function (message) { alert("Problem retrieving XML data"); if (this.onerror) { this.onerror.call(this,message); } } } var Com = { isIE6 : (/MSIE 6/.test(navigator.appVersion)), hasHashchange : function() { if ("onhashchange" in window) { return true; } return false; } }; function PageLoad () { this.iframeObj = null; this.iframeWin = null; this.iframeSrc = this.iframeSrc || 'history.html'; this.location = this.location || window.location; this.tab = null; this.output = null; this.tabs = null; } PageLoad.prototype = { create : function() { if (Com.hasHashchange) { return; } if (!this.iframeObj) { var ifr = document.createElement_x('iframe'); ifr.name = 'hashIframe'; ifr.id = 'HashIframe'; ifr.style.display = 'block'; document.body.appendChild(ifr); } }, bindTabEvent : function() { var self = this; try { var tabs = this.tabs; for (var i = 0,l = tabs.length; i < l; i++) { tabs[i].onclick = function(evt) { var ele = (event.srcElement || event.target || evt.srcElement); var tg = self.toogleTab(ele); return false; } } } catch (e) { alert(e); } }, bindHashEvent : function() { // bind onhashchange event var self = this; onhashchange = function() { self.pageLoadDone(); } }, bindIframeEvent : function() { var self = this; var ifr = self.iframeObj; var ifrWind = self.iframeWin; if (ifr.attachEvent) { ifr.attachEvent('onload',function() { self.iframeLoadDone(); }); } else { ifr.onload = function() { // self.iframeLoadDone.call(this,self); self.iframeLoadDone(); }; } }, loadDefaultPage : function() { var tabname = 'tab1'; if (Com.hasHashchange) { if (this.getHash() == '') { // 如果页面hash值为空,则更改hash为初始化的值 this.setHash(tabname); } else { // 如果是带hash访问则直接通过hash值回溯页面 var tab = this.getHash().split('#')[1]; this.loadDone(tab); } } else { // 如果是不支持onhashchange的浏览器,如ie6等采用iframe this.iframeObj.src = this.iframeSrc + '?tab=' + tabname; }
}, init : function() { if (!this.iframeObj) { this.create(); } this.iframeObj = document.getElementByIdx_x('HashIframe'); this.iframeWin = window.frames['hashIframe']; this.tab = document.getElementByIdx_x('tab'); this.output = document.getElementByIdx_x('output'); this.tabs = this.tab.getElementsByTagName_r('a'); this.bindTabEvent(); if (Com.hasHashchange) { this.bindHashEvent(); } else { this.bindIframeEvent(); } this.loadDefaultPage(); }, loadDone : function(tab) { if ('string' != typeof tab) { return; } try { var idx = tab.substr(3) - 1; var tabs = this.tabs; var _callBack = function(data) { output.innerHTML = data; } this.getContent(tabs[idx],_callBack); this.toggle(tabs[idx]);
} catch (e) { alert(e.message); } }, pageLoadDone : function() { var hash = this.getHash(); tab = hash.split('#')[1]; this.loadDone(tab); }, iframeLoadDone : function() { var hash = this.iframeWin.location.search; var tab = hash.split('=')[1]; this.loadDone(tab); }, toggle : function(ele) { var tabs = this.tabs; var idx = 0; for (var i = 0,l = tabs.length; i < l; i++) { if (ele != tabs[i]) { tabs[i].className = ''; } else { tabs[i].className = 'selected'; } } }, toogleTab : function (ele) { // 更改hash,以便浏览器监听 if ( !(ele.nodeType == 1) ) { return false; } var tabname = ele.getAttribute('tabname'); this.setSelectedTab(tabname); this.toggle(ele); return false; }, setHash : function(hash) { //window.location = 'location.html#tab=tab' + idx; // window.location.hash = hash; window.location.hash = hash; }, getHash : function() { var hash = window.location.hash; return hash; }, setSelectedTab : function(tabname) { if (Com.hasHashchange) { this.setHash(tabname); } else { this.iframeObj.src = this.iframeSrc + '?tab=' + tabname; } }, getContentByTarget : function(evt,callBackFun) { this.getContent(evt.srcElement); }, getContent : function(ele,callBackFun) { var ajax = new Ajax(); var output = this.output; var _callBack = function(data) { if (typeof callBackFun == 'function') { callBackFun(data); } else { // output.innerHTML = data; } }; output.innerHTML = 'loading...'; var url = ele.href + '?t=' + Math.random() * 100; var data = { item : ele.href,'href' : ele.href }; ajax.get(url,'json',_callBack ); } } window.onload = function() { new PageLoad().init(); } </script> <br> <h1>Ajax浏览器前进后退</h1> <h4> 本例通过隐藏location hash来实现前进后退,更改location.hash,然后通过onhashchange事件来监听hash变化,通过hash值来还原页面,不支持onhashchange事件的浏览器如ie6还是需要通过iframe模拟来实现。<a href="location2.html">查看iframe版本</a></h4> <div class="tab" id="tab"> <a href="data1.txt" tabname="tab1" class="selected">tab1</a><a href="data2.txt" tabname="tab2">tab2</a><a tabname="tab3" href="data3.txt">tab3</a> </div> <div class="content"> <pre id="output"> <strong>Loading Ajax接收显示的内容:</strong> </pre> </div> </body> </html> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |