Aajx实现无数据刷新时,我们会遇到浏览器前进后退失效的问题以及URL不友好的问题。

实现方式有两种

1、支持onhashchange事件的,通过更新和读取location.hash的方式来实现

/*

因为Javascript对dom的操作是不持久化的,刷新后就恢复原状,而且也不保存历史记录,也就无法前进后退来查看历史了。但是可以采用“地址栏加hash”技术来解决。
地址栏中敲入“页面地址#aaa”就表示跳转到“页面地址 ”的“aaa”这个页内锚点(英文叫做hash)。只要改变“aaa”这个锚点内容,浏览器就认为URL变化,也就会放入浏览历史,这样前进后退问题就解决了。我们只要把不同的AJAX状态通过不同的hash写到地址栏就可以了,当页面加载的时候检测是否有hash值,有的话就读取hash进行相应的ajax还原操作。
location.hash可以取到或者设置hash的值,当hash改变的时候window.onhashchange事件会被触发,但是页面加载的时候哪怕有hash值,onhashchange事件也不会触发,因此需要在onload事件中也读取hash进行同样的处理,保证刷新页面也能恢复ajax的页面显示。
下面是例子代码,为了简单的突出问题,这里没有使用ajax,只是通过dom来修改页面状态。点击文本框,文本框的内容会加1(注意观察地址栏),刷新页面后值也还是增加后的值,而且页面可以前进后退。
代码如下:
[html]
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<Meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>TestDemo</title>
<script src="jquery-1.4.2-min.js"></script>
<script type="text/javascript">
var processHash = function () {
var hashStr = location.hash.replace("#","");
if (hashStr) $("#txt1").val(hashStr);
}
$(function () {
$("#txt1").click(function () {
var i = parseInt($("#txt1").val());
i++;
$("#txt1").text(i);
location.hash = "#" + i;
});
window.onload = processHash;
window.onhashchange = processHash;
</script>
</head>
<body>
<input type="text" id="txt1" value="1" />
</body>
</html>

*/

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>

ajax实现浏览器前进后退-location.hash与模拟iframe的更多相关文章

  1. 详解Html5页面实现下载文件(apk、txt等)的三种方式

    这篇文章主要介绍了详解Html5页面实现下载文件(apk、txt等)的三种方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 详解使用postMessage解决iframe跨域通信问题

    这篇文章主要介绍了详解使用postMessage解决iframe跨域通信问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. 基于HTML十秒做出淘宝页面

    十分钟做出一个网页,看似不可思议,下面小编给大家带来了基于HTML十秒做出淘宝页面,只分为两步,代码超级简单,需要的朋友参考下吧

  4. html5唤起app的方法

    这篇文章主要介绍了html5唤起app的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. 跨域修改iframe页面内容详解

    这篇文章主要介绍了跨域修改iframe页面内容详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. 使用postMessage让 iframe自适应高度的方法示例

    这篇文章主要介绍了使用postMessage让 iframe自适应高度的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  7. ios – didUpdateLocations从未调用过

    我正在尝试获取用户的位置.为此,我在info.plist中设置了以下属性:我还在viewDidLoad方法中添加了以下代码以及下面的函数.问题是locationManager(manager,didUpdate…

  8. ios – 重命名并重写为Swift后对象解码崩溃

    由于我们已经重命名了(Bestemming–>Place)类并将其从Objective-c重写为Swift,因此一些用户会遇到崩溃.我们正在尝试使用NSCoding原则从NSUserDefaults加载对象.碰撞:班级:从NSUserDefaults阅读:崩溃日志说它在第0行崩溃,这是注释所以我认为它在init方法中崩溃,我认为它与一个null为空但不能为null的对象有关.我尝试过的:>尝试在S

  9. 适用于iOS的Google Maps SDK不断增加内存使用量

    我已经构建了一个在地图上显示标记的简单应用程序,我从服务器的JSON文件加载其x,y,标记是可点击的,所以一旦你在任何标记上它将你带到另一个UIViewController(我们将它命名为BViewController).我已经监视了内存使用情况,所以每次我从BViewController返回到MapViewController(里面的地图)时,它只是内存使用量的两倍我尝试将其设置为nill或从s

  10. ios – 未提示在应用程序中启用位置服务

    更新:这不是重复.我已经在info.plist中添加了所需的密钥,如我原始问题中所述,问题仍然存在.我已经尝试了各种组合的所有三个键.在任何人感到不安之前,我已阅读了许多AppleDev论坛帖子和堆栈溢出帖子,无法弄清楚为什么我的应用程序拒绝提示用户允许使用时授权.我已将以下密钥添加到我的Info.plist文件中,并附带一个String值:然后我写了(在Swift和Obj-C中)应该提示用户的代

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部