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

  • 相关阅读:
    LeetCode Missing Number (简单题)
    LeetCode Valid Anagram (简单题)
    LeetCode Single Number III (xor)
    LeetCode Best Time to Buy and Sell Stock II (简单题)
    LeetCode Move Zeroes (简单题)
    LeetCode Add Digits (规律题)
    DependencyProperty深入浅出
    SQL Server存储机制二
    WPF自定义RoutedEvent事件示例代码
    ViewModel命令ICommand对象定义
  • 原文地址:https://www.cnblogs.com/zhaopei/p/ajax_fallback.html
Copyright © 2011-2022 走看看