【问题标题】:How do you handle busy icons in an AJAX site?您如何处理 AJAX 站点中的繁忙图标?
【发布时间】:2008-12-09 18:28:33
【问题描述】:

此问题涉及并发问题,有关如何显示忙碌图标的建议,请参阅此问题:Javascript - loading/busy indicator or transparent div over page on event click

当用户在页面上发起 AJAX 请求时,显示某种“工作”或忙碌图标或进度指示器很有用。如果只有一个长时间运行的进程,则可以以相对简单的方式处理:

function do_action() {
   show_busy_icon();       

   long_running_asynchronous_process(function() {
      // Callback function run when process finishes
      hide_busy_icon();
   });
}

但是,如果页面上正在运行多个异步进程,则使用 on/off 方法将不起作用。即使有其他进程正在运行,第一个完成的进程也会关闭图标。

那么,您如何处理在网页上显示一个指示器,即当有一个或多个进程在运行时打开,当没有进程在运行时关闭?

我想可以保持对正在运行的进程数的计数。 hide_busy_icon() 仅在进程计数为 0 时隐藏图标。这似乎有点容易失败。也许我没有看到更好/更简单的方法。

感谢您的想法和建议!

编辑:在使用标记答案中的解决方案一段时间后,我很高兴地说它运行良好。我遇到的唯一问题是我自己的脚本调用我无法控制的脚本函数的情况。除非这些函数允许提供回调,否则无法在它们开始和结束时更新进程计数。

可能发生这种情况的一个示例是向 Google 地图添加一组标记。一旦我的脚本调用 Google 地图功能,忙碌图标就会消失,而标记仍在加载中。

我不确定处理这个问题的好方法。

【问题讨论】:

    标签: javascript jquery ajax concurrency callback


    【解决方案1】:

    如果您希望所有操作都使用相同的忙碌指示器,请使用计数器。

    代替“show_busy_icon()”,执行“increment_busy_count()”,如果忙计数从 0 变为 1,则调用“show_busy_icon()”。代替“hide_busy_icon()”,执行“decrement_busy_count()” ,如果忙碌计数从 1 变为 0,则调用“hide_busy_icon()”。

    【讨论】:

      【解决方案2】:

      我认为问题在于您只使用了一个指标。为每个需要的操作设置一个指示器可能会更容易。

      因此,如果您在一个页面上进行多次搜索,每个搜索区域都会有它自己的独立指示器,在相应的 javascript 函数中显示或隐藏。

      【讨论】:

        【解决方案3】:

        Prototype 有这个内置的;一个名为Ajax.activeRequestCount 的属性跟踪在任何给定时间有多少请求处于活动状态。它还允许您设置全局 Ajax 响应程序以确定是隐藏还是显示“忙碌”图标。

        【讨论】:

          【解决方案4】:

          请看我的回答:

          How to display a loading screen while site content loads

          我给出了一个小的、有效的 JavaScript 示例来说明如何做到这一点,希望对您有所帮助。

          【讨论】:

          • 我认为您的示例无法解决问题。假设您有两个 url:url1 和 url2.url1 需要 1 秒加载,而 url2 需要 5 秒加载。调用 load(url1) 和 load(url2) 他们都显示忙图标。
          • 1 秒后 url1 返回响应并关闭忙碌图标。您有 4 秒时间 url2 正在工作但没有显示图标。
          【解决方案5】:

          我提出了一个不同的解决方案。 这不是经过测试的代码,可能无法正常工作,但只是对概念的说明。

          我假设相同的精确操作不会在多个实例中运行。 我这样做是为了确保通信中的超时或类似问题不会挂起指示器,而是允许在重新建立通信时解决指示器

           var actionRegister = new Array();
          
           function register_action(actionId)
           {
               show_busy_icon();       
               if(blockedTile.indexOf(actionId) != -1)
               {  // element already registered
                  return;
               }
               actionRegister.push(actionId)
          }
          
          
          function unregister_action(actionId)
          {
              var idx = blockedTile.indexOf(actionId);
              if(idx  != -1)
              {  
                  actionRegister.splice(idx,1);
              }
          
              if(actionRegister.length < 1)
              {
                 hide_busy_icon();
              }
          }
          

          【讨论】:

            【解决方案6】:

            我们都以错误的方式看待它。 Ajax 调用用于使用 XHR 加载内容。这意味着在加载内容的整个 DOM 中必须有一些预定义的元素。 假设我们有一个这种类型的 html:

            <html>
            <body>
               <div id="content_1">
               </div>
               <div id="content_2">
               </div>
            </body>
            </html>
            

            使用 jQuery,假设我们要分别从 content_1.php 和 content_2.php 加载到 content_1 和 content_2。

            使用以下脚本处理 ajax::

            $("content_1").html("<img src='loading.gif'>").load("http://samplesite.com/content_1.php");
            
            $("content_2").html("<img src='loading.gif'>").load("http://samplesite.com/content_2.php");
            

            这将在各自的 div 中放置一个加载 gif,该 gif 稍后将被 php.ini 中加载的内容替换。简单的一行脚本。无需计数器。

            要求:任何最新版本的 jQuery。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-12-08
              • 2017-09-27
              • 2010-09-09
              • 2016-05-11
              • 2010-12-22
              • 2016-04-27
              • 2011-05-02
              相关资源
              最近更新 更多