如何让AJAX触发浏览器的加载指示器

43

我正在制作一个支持ajax的实验室预约程序,其中一些ajax操作不是非常快速。

在Gmail中,当您进入收件箱、发送邮件等操作时,浏览器会像加载新页面一样表现(在Firefox中,停止按钮变为可用状态,进度条出现),但实际上这些操作是通过AJAX完成的。

他们是如何做到的呢?我有一个旋转指示器,但如果能让浏览器表现得像正在加载就更好了。你有什么想法吗?


你有什么问题?你是想在网页中添加“加载”图像吗? - Jason
8
不,我试图触发浏览器的“加载”状态(当你加载一个页面时,会出现进度条等)。 - Michele N.
我能想到的唯一方法是触发 XHR 请求,然后在页面中添加一个 iframe 元素,加载一个“ping”页面(这个页面在 XHR 结束之前不会响应,这意味着它可能需要像 sessions 这样的服务器端锁),并在该 iframe 上放置事件处理程序以处理浏览器的加载取消。完成 iframe 加载后,请别忘了修复历史记录。 - Xenos
为什么不尝试反向工程Gmail的操作呢? 在Chrome中,右键单击元素,选择检查,选择body标签,右键单击它,选择断开子树修改。 现在刷新页面并查看它断开的时间 - 它仍会显示页面正在加载。 - Zlatin Zlatev
6个回答

8
我认为这个是你的答案(来自Obviously.com的Reverse-AJAX或“Slow Load”技术)。
看起来像GMail和Facebook的方法(浏览器显示页面正在“加载”并带有加载图标等 - 这只是模拟,因为有一个后台ajax请求) :)

2
我不明白这个问题和你提到的Reverse-AJAX技术之间的关系! - Alireza Mirian
1
这个回答的想法是在页面上创建一个iframe,iframe的src指向一个永远加载的页面。只要iframe正在尝试加载,这将导致浏览器的加载指示器出现。 - Doug S

5

6
似乎只能在 Firefox 中使用。在 Chrome 20 和 IE 9 中无法使用。 - josh3736

4
许多用户甚至不理解或注意浏览器的本机加载指示器。如果真的是长时间运行的加载,则最好将其作为您的Web应用程序的一部分进行指示。请记住,上下文是王道,这是向用户传达正在发生什么以及什么功能仍然可用的机会。
如果在请求时整个用户界面变得无效,则适用带有加载指示器的叠加层。略微不透明的叠加层可以在不影响视线的情况下向用户传达信息。
如果您只需要显示请求已启动并正在工作,则最好在启动请求的按钮旁边放置一个旋转器。成功后,旋转器可以替换为绿色勾号或其他常见指示器,并在短时间后淡出。
这些都是谷歌许多应用程序中发现的常见模式。

3
我感谢您的回答,但我有充分的理由想要使用浏览器指示而不是自定义指示。 - brillout
2
是的,从用户界面的角度来看,这更有意义。 如果这实际上是取消请求的一种方式,或者至少告诉您的页面取消它,那么使用浏览器按钮就有意义了。 我对此非常感兴趣! - Stefan Balan
1
许多用户甚至不理解或注意到浏览器的本地加载指示器。这个第一句话肯定是错误的。完全应该有一个本地API来处理这个问题。正确的用户体验应该是按照OP的要求触发浏览器的加载指示器。 - adriendenat
这绝对是一个不错的想法,@adriendenat。当跨浏览器API可用时,请告诉我们。 - N-ate

2

这篇文章详细介绍了不同类型的请求以及它们是否会触发繁忙指示器(例如进度条)。


嗯,有趣。我能调用某个函数吗?或者有什么触发它的东西(我不想改变所有我的请求类型和其他东西)? - Michele N.
1
很遗憾,这篇文章已经过时了,至少对于Chrome来说是这样。 - brillout

-2

可能的解决方案是使用iframe来触发加载。但根据之前的回答,iframe方法在Chrome上无法工作。

您的需求是在浏览器上显示加载图标,所以我认为另一种方式是创建一个假的加载图标

您可以手动更新浏览器图标。有一些关于如何更新浏览器图标的教程。

然后,尝试使图标动起来。大多数浏览器不支持gif图标,所以您需要每隔几秒钟更新一次图标。

这是演示代码:

 var favicon_images = [];
 for (var i = 1; i <= 12; i++)
   favicon_images.push('./icon/' + i + '.png');

 var image_counter = 0;

 setInterval(function() {
     var link = document.querySelector("link[rel*='icon']") || document.createElement('link');
     link.type = 'image/x-icon';
     link.rel = 'shortcut icon';
     link.href = favicon_images[image_counter];
     document.getElementsByTagName('head')[0].appendChild(link);

   if(image_counter == favicon_images.length -1)
         image_counter = 0;
     else
         image_counter++;
 }, 150);

我创建了一个快速演示。Demo

通过这个演示,你可以发现图标动画没有平滑运行。这是因为每次更新图标时,浏览器都会再次请求图标。

所以将图像转换为base64格式,它就可以平稳地工作。

Base64演示

现在,你只需要找到与Chrome和其他流行浏览器相同的加载图标,然后在调用ajax时触发假加载即可。


这里我贴上一些更改图标的教程:


1
因为这不是 OP 所要求的,所以我会给你点个踩。但是,我会把悬赏给你,因为你的回答比其他人的更好。 - brillout

-2

我相信你想要的是这样的。

我已经添加了一个API来获取github.com的地理位置(虽然不相关,但我认为它可以作为示例API)。

这是一个简单的JavaScriptJQuery代码,用于在进行AJAX请求时显示/隐藏加载指示器。

$('#btn').click(function() {
  $('#overlay').show();
  $.ajax('https://freegeoip.net/json/github.com').then(function(response) {
    $('#overlay').hide();
    $('#country').html(response.country_name);
  });
});
body {
  padding: 0;
  margin: 0;
}

#overlay {
  position: fixed;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  top: 0;
  background-color: rgba(255, 255, 255, 0.7);
}

.plus {
  display: flex;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="overlay" style="display:none">
  <div class="plus">
    <img src="https://loading.io/assets/img/landing/curved-bars.svg" alt="loading"/>
  </div>
</div>

<div>
  <button id="btn">Perform AJAX Operation</button>
  <div>
  Country: <span id="country"></span>
  </div>
</div>


1
感谢您的回答,但我想使用浏览器指示,而不是自定义指示器。因为 OP 已经非常清楚了,所以我要给他们点个踩。 - brillout
然后,您可以在body上添加光标属性为wait - Vipin Kumar
这仍然是定制行为,而不是标准的“本地”浏览器行为。 - brillout

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接