需求1:

  • ajax异步请求
  • url标识请求参数(也就是说复制url在新页面打开也会是ajax后的效果)

ajax异步请求没问题,问题一般出在刷新url后请求的数据没了,这就是因为url没有记录参数。如果我们改变给url添加参数,这样就改变了url,也就会重新请求整个url。这样一来就没有了ajax的优势和作用了。那么,我们应该怎么保持参数而又不重新请求url呢?做过单页面SPA (Single-page Application)的都知道,我们可以使用描点来实现(因为修改描点的时候,不会发送url的重新请求)。

如,博客园的分页就是如此

demo1:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
ul {
list-style: none;
} ul li {
float: left;
margin-left: 10px;
}
</style>
</head>
<body>
<div style="color: red; margin-left: 50px; ">demo1(默认的回退效果)</div>
<div>
<ul>
<li><a href="#tab1">tab1</a></li>
<li><a href="#tab2">tab2</a></li>
<li><a href="#tab3">tab3</a></li>
<li><a href="#tab4">tab4</a></li>
<li><a href="#tab5">tab5</a></li>
</ul> </div>
<input style="margin-left:15px" type="button" value="回退" onclick="history.go(-1)" />
<a href="home.html">主页</a>
<div class="content" style="font-size:44px;color:red;margin-top:50px;text-align:center"> </div> <script src="../../Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//刷新url时停留ajax的效果
var hash = window.location.hash;
$("ul").find("a[href='" + hash + "']").click();
})
$("ul").click(function (e) { if (e.target.localName != "a") return; var value = $(e.target).attr("href");
$.get("temp.html", value, function (obj) {//ajax的get请求
//请求发送成功后修改页面元素内容
$(".content").html("我是" + value);
}, "text");
});
</script>
</body>
</html>

效果图:

我们认真看上面的gif动态图,会发现点击tab的ajax异步加载完全没问题,只是我们点击回退的时候 虽然url的描点变了,可是内容没变。(博客园的分页回退就是这个效果)这肯定是不太好的效果。(对history.go()不太了解的请戳

需求2:

  • ajax异步请求
  • url标识请求参数(也就是说复制url在新页面打开也会是ajax后的效果)
  • 点击“回退”页面要可以回到“主页”

通过观察上面的gif动图,我们发现回退的顺序正是,url的改变记录顺序。那我们在每次点击一个ajax请求累加一次计数,这样是不是就可以一次性退回“主页”呢?

demo2:

<input style="margin-left:15px" type="button" value="回退" onclick="go()" />
<a href="home.html">主页</a>
<div class="content" style="font-size:44px;color:red;margin-top:50px;text-align:center"> </div>
<script src="../../Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//刷新url时停留ajax的效果
var hash = window.location.hash;
$("ul").find("a[href='" + hash + "']").click();
}) var num = -1;
$("ul").click(function (e) {
num--;
if (e.target.localName != "a") return; var value = $(e.target).attr("href");
$.get("temp.html", value, function (obj) {
$(".content").html("我是" + value);
}, "text");
}); function go() {
history.go(num)
}
</script>

效果图:

ok,效果是我们要的。可是需求又说了,感觉这样还是不太好,回退应该是返回上一次的点击效果。

需求3:

  • ajax异步请求
  • url标识请求参数(也就是说复制url在新页面打开也会是ajax后的效果)
  • 点击“回退”返回上一次的点击效果

拿到需求开始头痛了,怎么回退到上一次点击效果呢?有没有什么回退事件呢?还好H5给我们准备了 window.onpopstate url监听事件。

demo3:

<input style="margin-left:15px" type="button" value="回退" onclick="history.go(-1)" />
<a href="home.html">主页</a>
<div class="content" style="font-size:44px;color:red;margin-top:50px;text-align:center"> </div> <script src="../../Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//刷新url时停留ajax的效果
var hash = window.location.hash;
$("ul").find("a[href='" + hash + "']").click();
}) $("ul").click(function (e) { if (e.target.localName != "a") return;//如果点击的不是a标签直接返回 var value = $(e.target).attr("href");
$.get("temp.html", value, function (obj) {
$(".content").html("我是" + value);
}, "text");
}); if (history.pushState) {
window.onpopstate = function () {
var hash = window.location.hash;
$("ul").find("a[href='" + hash + "']").click();
}
}
</script>

效果图:

乍一看,好像很完美了(url和内容同时发生了对应的改变)。其实不然。我们debugger调试一看便知。

仔细看上图,你会发现  $("ul").click( a标签出现了两次点击事件(这明显是有瑕疵的),首先直接点击a标签触发,然后改变了url导致触发onpopstate事件,然后在onpopstate事件里面又一次点击a标签,最后导致了两次执行a标签点击事件。

那么如何,避免执行两次a标签的点击事件呢?思路肯定是怎样在修改url的时候不触发onpopstate事件,只有在前进和回退的时候触发。这里就要用到 history.pushState 了。

需求4:

  • ajax异步请求
  • url标识请求参数(也就是说复制url在新页面打开也会是ajax后的效果)
  • 点击“回退”返回上一次的点击效果(但是不能执行多余代码)
 <script type="text/javascript">
$(function () {
//刷新url时停留ajax的效果
var hash = window.location.hash;
$("ul").find("a[href='" + hash + "']").click();
}) $("ul").click(function (e) {
debugger
e.preventDefault();//不要执行与事件关联的默认动作 if (e.target.localName != "a") return;//如果点击的不是a标签直接返回 var value = $(e.target).attr("href");
$.get("temp.html", value, function (obj) {
$(".content").html("我是" + value);
if (e && e.clientX) //用来判断是否是鼠标点击触发
history.pushState(null, value, location.href.split("#")[0] + value);//塞入历史记录,并改变当前url
}, "text");
}); if (history.pushState) {
window.onpopstate = function () {
debugger;
var hash = window.location.hash;
$("ul").find("a[href='" + hash + "']").click();
debugger
}
}
</script>

(这需要注意  if (e && e.clientX) //用来判断是否是鼠标点击触发 如果没有这句,那么每次触发onpopstate 的时候往历史记录里面塞进去一条,那样就死循环出不来了。)

效果图:

明显可以看出只执行了一次a标签的点击事件,且回退功能也是正常。按道理,现在已经是完美了。不过,我们回过头来想想,我们为什么一定要使用锚点来记录参数呢。以前是因为修改锚点不会重新请求url而巧用了锚点。现在我们通过history.pushState把url塞入历史记录的时候,也改变了当前url且也没有对url发送请求,那我们是不是没有必要使用锚点了呢?答案是确定的。

需求4:

  • ajax异步请求
  • url标识请求参数(也就是说复制url在新页面打开也会是ajax后的效果)
  • 点击“回退”返回上一次的点击效果(不使用描点)

其实,直接把上面代码修改部分就可以了。

demo4:

 <script type="text/javascript">
$(function () {
//刷新url时停留ajax的效果
var hash = location.href.split("?")[1];
$("ul").find("a[href='" + hash + "']").click();
}) $("ul").click(function (e) {
e.preventDefault();//不要执行与事件关联的默认动作 if (e.target.localName != "a") return; var value = $(e.target).attr("href");
if (e && e.clientX) //用来判断是否是鼠标点击触发
history.pushState(null, null, location.href.split("?")[0] + "?" + value);//塞入历史记录,并改变当前url
$.get("temp.html", value, function (obj) {
document.title = value;
$(".content").html("我是" + value);
}, "text");
}); if (history.pushState) {
window.addEventListener("popstate", function () {
var hash = location.href.split("?")[1];
$("ul").find("a[href='" + hash + "']").click();
});
}
</script>

效果图:

完整演示地址:http://hi.haojima.net/demo/history/home.html

以上内容都是胡说八道。

好了,关于ajax回退效果就分析到这里了。感谢您的阅读,希望对您有一点点作用。

文章首链:http://www.cnblogs.com/zhaopei/p/5637889.html

一步步学习javascript基础篇(9):ajax请求的回退的更多相关文章

  1. 一步步学习javascript基础篇(0):开篇索引

    索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...

  2. 一步步学习javascript基础篇(3):Object、Function等引用类型

    我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...

  3. 一步步学习javascript基础篇(8):细说事件

    终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...

  4. 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

    上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...

  5. 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)

    前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...

  6. 一步步学习javascript基础篇(1):基本概念

    一.数据类型 数据类型 基本数据类型(五种) Undefined Null Boolean Number String 复杂数据类型(一种) Object Undefined:只有一个值undefin ...

  7. 一步步学习javascript基础篇(7):BOM和DOM

    一.什么是BOM.什么是DOM BOM即浏览器对象模型,主要用了访问一些和网页无关的浏览器功能.如:window.location.navigator.screen.history等对象. DOM即文 ...

  8. 一步步学习javascript基础篇(6):函数表达式之【闭包】

    回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; }  //函数声明语法定义 2. var sum = funct ...

  9. 一步步学习javascript基础篇(2):作用域和作用域链

    作用域和作用域链 js的语法用法非常的灵活,且稍不注意就踩坑.这集来分析下作用域和作用域链.我们且从几道题目入手,您可以试着在心里猜想着答案. 问题一. if (true) { var str = & ...

随机推荐

  1. python自动化测试(2)-自动化基本技术原理

    python自动化测试(2) 自动化基本技术原理 1   概述 在之前的文章里面提到过:做自动化的首要本领就是要会 透过现象看本质 ,落实到实际的IT工作中就是 透过界面看数据. 掌握上面的这样的本领 ...

  2. C语言 · 4-3水仙花数

    问题描述 打印所有100至999之间的水仙花数.所谓水仙花数是指满足其各位数字立方和为该数字本身的整数,例如 153=1^3+5^3+3^3. 样例输入 一个满足题目要求的输入范例.例:无 样例输出 ...

  3. jsp前端实现分页代码

    前端需要订一page类包装,其参数为 private Integer pageSize=10; //每页记录条数=10 private Integer totalCount; //总记录条数 priv ...

  4. IOS FMDB 获取数据库表和表中的数据

    ios开发中,经常会用到数据库sqlite的知识,除了增,删,改,查之外,我们说说如何获取数据库中有多少表和表相关的内容. 前言 跟数据库使用相关的一般的增删改查的语句,这里就不做解释了.在网上有很多 ...

  5. 应该是Angular2的一个bug?

    为了应对未来的趋势,及时赶上下一趟互联网技术,我最近也在通过具体项目研究angular2,首先必须要吐槽的是,学习angular2的成本本身不高,但是一堆的工具.配置实在让人 很是焦灼,就像asp.n ...

  6. 如何理解javaSript中函数的参数是按值传递

    本文是我基于红宝书<Javascript高级程序设计>中的第四章,4.1.3传递参数小节P70,进一步理解javaSript中函数的参数,当传递的参数是对象时的传递方式. (结合资料的个人 ...

  7. DevExpress - 使用 GaugeControl 标尺组件制作抽奖程序 附源码

    前不久,公司举办了15周年庆,其中添加了一个抽奖环节,要从在读学员中随机抽取幸运学员,当然,这个任务就分到了我这里. 最后的效果如下,启动有个欢迎页面,数据是来自Excel的,点击开始则上面的学号及姓 ...

  8. Windows下MySQL无法启动

    问题描述: 从网上下了5.7 的MySQL,在bin目录下执行 start mysqld ,弹出个cmd窗口一闪就没了,也看不清是什么报错.mysqld --install安装了服务,也启动不了.   ...

  9. linux系统维护时的一些小技巧,包括系统挂载新磁盘的方法!可收藏!

    这里发布一些平时所用到的小技巧,不多,不过会持续更新.... 1.需要将history创建硬链接ln 全盘需要备份硬链接 ln /etc/xxx /home/xxx 2.root用户不可以远程 /et ...

  10. 项目游戏开发日记 No.0x000001

    14软二杨近星(2014551622) 既然已经决定了开发软件, 时不时就要练练手, 还要时不时的去寻找素材, 因为开发的人物设定就是DotA2里面的祈求者, 所以, 就去找了他的相关人物图片和模型, ...