zoukankan      html  css  js  c++  java
  • 一步步学习javascript基础篇(9):ajax请求的回退

    需求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

  • 相关阅读:
    SPOJ
    SPOJ LCS Longest Common Substring(后缀自动机)题解
    HihoCoder1445 后缀自动机二·重复旋律5(后缀自动机 子串种数)
    eclipse 常用设置
    读取Request body方法
    pom.xml实例
    powerdesign连接Oracle&Mysql
    Json常用操作
    Spring MVC POM示例
    FreeMaker常用表达式
  • 原文地址:https://www.cnblogs.com/zhaopei/p/ajax_fallback.html
Copyright © 2011-2022 走看看