Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

为页面跳转添加进度条

  国外很多网站比如youtube和twitter等都有如此的实现,当点击一个站内链接时不是进入无尽的等待,而是有一个真实的进度条显示跳转页面的加载进度。从IE8开始就可以为程序发起的请求提供进度信息了,所以这是通过程序可以实现的,只是有点颠覆传统。

  如何获取程序发起请求的加载进度我就不细说了,XHR有progress事件,IE8的实现可以看这里
  首先,当用户点击站内链接时我们应该阻止超链接的默认行为,通过程序来向服务器发起请求,这样才可以获得加载的进度信息。但现在的问题是,如何在加载完成后显示加载后的页面?其实在一些大型框架中把一些加载封装地很细,他们发起的请求根本不是对页面的请求,而是直接针对所需数据的请求,在获取这些数据后通过MVVM之类的方式显示出来而已。地址栏可以通过HistoryAPI来切换,也可能只是hash的变化。所以在这样的大框架下实现加载的进度条根本不成问题。
  但如果没有这样的框架呢?其实有个很取巧的办法,利用缓存来解决。当我们访问一个URL时,无论是浏览器的直接浏览还是程序发起的请求,都会根据资源的头信息做响应的缓存处理。只要对页面设置一个短暂的缓存,当用程序加载时就把这个页面缓存到本地了,之后让页面直接跳转到这个URL上也不会再次向服务器发起请求。下面是这个做法的演示,这里没做低版本IE的兼容
<?
//关闭GZIP方便测试
@apache_setenv('no-gzip',1);
@ini_set('zlib.output_compression','Off');
ob_start();
?>
<script>
document.addEventListener("click",function(e){
  if(e.target.tagName!="A"||!e.target.href)return;
  var xhr=new XMLHttpRequest;
  progress.style.display="block";
  xhr.open("GET",e.target.href,true);
  xhr.onprogress=function(e){
    //处理进度条
    progress.max=e.total;
    progress.value=e.loaded;
  };
  xhr.onload=function(){
    location.href=e.target.href;
  };
  xhr.send();
  e.preventDefault();
});
</script>
<progress id="progress" style="display:none;"></progress>
<a href="?1">1</a>
<a href="?2">2</a>
<a href="?3">3</a>
<?
$data=ob_get_contents();
$length=strlen($data);
while(ob_get_level())ob_end_clean();
header('Content-Length: '.$length);
header('Cache-Control: max-age=60'); //开启缓存

//模拟渣网络的环境输出数据
for($i=0;$i<$length/10;$i++){
  usleep(50*1E3);
  echo substr($data,$i*10,10);
  flush();
};
?>
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^