代码之家  ›  专栏  ›  技术社区  ›  Mike

jquery+ajax+loading spinner image=太快了!

  •  1
  • Mike  · 技术社区  · 16 年前

    我正在我的ASP.NET MVC 2页面中使用jquery。这是一个非常简单的帖子,可以得到一个日期作为回报。这个过程本身运行得很快。我想用一个旋转图像向用户显示正在发生的事情。在火狐中一切正常,在本地测试。然而,在IE8中,自旋体图像的显示时间不够长;它只是闪烁。如果最终用户看不到进程正在工作/完成的指示,这可能会混淆最终用户。解决这个问题的最佳方法是什么?

    谢谢。

     <img id="signedout<%: item.Id %>" src="/Content/Images/signed_out.png" alt="Signed Out" title="Signed Out" style="display:none" />
                    <div id="ajaxloader<%: item.Id %>" style="display:none;text-align:center"><img src="/Content/Images/ajax-loader.gif" alt="loading..." title="loading..." /></div>
    
                    <script type="text/javascript">
                        $(function () {
                            var id = "<%: item.Id %>";
    
                            $("#signout" + id).click(function () {
                                if (confirm("Are you sure you want to sign this visitor out?")) {
    
                                    $(this).hide();
                                    //$("#signout" + id).hide();
                                    $("#ajaxloader" + id).show();
    
                                    var url = '<%: Url.Action("signout") %>';
    
                                    $.ajax({
                                        type: "POST",
                                        url: url,
                                        data: "id=" + id,
                                        success: function (result) {
                                            $("#timeout" + id).append(result);
                                            $("#ajaxloader" + id).hide();
                                            $("#signedout" + id).show();
                                            $("#row" + id).css("background", "#E8E8E8");
                                        },
                                        error: function () {
                                            alert("There was an unexpected error.  Please try again later.");
                                            $("#ajaxloader" + id).hide();
                                            $("#signout" + id).show();
                                        }
                                    });
                                }
                            });
                        });   
                    </script>
    
    4 回复  |  直到 16 年前
        1
  •  1
  •   amurra    16 年前

    您可以在JS中设置一个超时,这样可以保证在超时过期之前自旋体不会被隐藏:

        function HideLoadingSpinner() {
            $("#ajaxloader" + id).hide();
        }
    

    然后将您的Ajax调用替换为以下调用:

        $.ajax({type: "POST",
                url: url,
                data: "id=" + id,
                success: function (result) {
                   $("#timeout" + id).append(result);
                   setTimeout(HideLoadingSpinner, 2000);
                   $("#signedout" + id).show();
                   $("#row" + id).css("background", "#E8E8E8");
                },
                error: function () {
                    alert("There was an unexpected error.  Please try again later.");
                    setTimeout(HideLoadingSpinner, 2000);
                    $("#signout" + id).show();
                }
        });
    

    如果由于计时器的原因而出现奇怪的行为,您也可以将success回调中的其他逻辑移动到hidingloadingspinner函数中。

        2
  •  3
  •   DLH    16 年前

    最好给出一些其他指示,说明过程已经完成,而不是在没有实际处理任何内容时错误地显示微调器。不管你怎么想。

    这是基于amurra的答案,并且设计为在加载进程后隐藏微调器,前提是并且仅当超时已经返回时。因此,如果Ajax请求返回“太快”,它将等待超时。

    var timeoutComplete=false;
    var requestComplete=false;
    
    function HideLoadingSpinner() {
       if(requestComplete) {
          $("#ajaxloader" + id).hide();
       } else {
          timeoutComplete=true;
       }
    }
    

    同时,在点击处理程序中…

    setTimeout(HideLoadingSpinner, 2000);
    
    $.ajax({type: "POST",
       url: url,
       data: "id=" + id,
       success: function (result) {
          $("#timeout" + id).append(result);
          $("#signedout" + id).show();
          $("#row" + id).css("background", "#E8E8E8");
          if(timeoutComplete) {
             $("#ajaxloader" + id).hide();
          } else {
            requestComplete=true;
          }
       },
       error: function () {
          alert("There was an unexpected error.  Please try again later.");
          $("#ajaxloader" + id).hide();
          $("#signout" + id).show();
       }
    });
    

    编辑: 我刚把 if(timeoutComplete) 来自于 error 函数,因为 alert 在它之前。

        3
  •  2
  •   Im0rtality    16 年前

    你不能在明亮的背景下显示“数据加载”消息,在重新加载后几秒钟内淡出吗?

        4
  •  1
  •   Ryan    16 年前

    我以前见过这个。实际上,你看到的是(用正常的时间运行请求 FF花费的时间比它应该花费的时间长 . 你可以设定 network.dns.ipv4OnlyDomains localhost 在里面 about:config 在本地主机上显著加速FF。 Source .

    在我自己的应用程序中,我遵循@im0rtality的建议,并收到一个通知,说明Ajax请求已完成,并在发生请求时显示微调器。很多次我都没看到旋转器。我用 custom implementation 我的通知是非常专业的。

    至于在Ajax调用期间显示微调器,您可以在母版页中包含它,以便在所有jquery Ajax调用期间显示微调器:

    $(function () {
        $('.spinner')
        .hide()
        .ajaxStart(function () {
            $(this).show();
        })
        .ajaxStop(function () {
            $(this).hide();
        });
    });
    

    那么,您不必每次调用都包括显示和隐藏微调器 $.ajax .