类似于YouTube的进度条

37

我正在尝试制作类似于YouTube的进度条。该进度条应在页面启动时加载。到目前为止,我已经尝试过以下代码:

这是我的脚本代码:

$({property: 0}).animate({property: 105}, {
    duration: 4000,
    step: function() {
        var _percent = Math.round(this.property);
        $('#progress').css('width',  _percent+"%");
        if(_percent == 105) {
            $("#progress").addClass("done");
        }
    },
    complete: function() {
        alert('complete');
    }
});

我还包含了同样的jsFiddlehttp://jsfiddle.net/ajaSB/3/

在这个 jsfiddle 中,进度条出现了,但是当我在我的 IDE 中使用相同的代码并运行文件时,没有进度条出现。我做错了什么吗?或者是否有另一种方法可以获得进度条?


是的,我正在正确地执行这个操作:<script type='text/javascript' src='js/progressbar.js'></script> <link href="css/progressbar.css" rel="stylesheet" type="text/css" /> - Swagata Barua
页面也没有错误……页面加载了,但进度条没有出现。 - Swagata Barua
@SwagataBarua:MarsOne 的意思是,如果你有 jQuery 库的引用,而不是你的 jQuery 代码。jQuery 是一个 JavaScript 库,你需要引用它,这样 jQuery 的功能才能使用。 - awe
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script> - MarsOne
你是否将代码块包裹在 document.ready 中?在 fiddle 中,你不一定需要这样做。 - kayen
显示剩余6条评论
6个回答

34

2
bower install nprogress,然后瞬间我们就有了YouTube进度条。 - shangxiao
请考虑添加库的内联示例用法,而不仅仅是第三方资源链接。 - Edric

19

以下是包含对jQuery库的引用的完整HTML页面示例。

尽管它大部分时间可以正常工作,但你应该将代码包装在$(document).ready(...)中,以确保在运行代码之前加载了所有必需的资源。

<!DOCTYPE html>
<html>
  <head>
  <title>Progress Test</title>

  <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>

  <script type="text/javascript">
    $(document).ready(function(){
      $({property: 0}).animate({property: 105}, {
        duration: 4000,
        step: function() {
          var _percent = Math.round(this.property);
          $("#progress").css("width",  _percent+"%");
          if(_percent == 105) {
            $("#progress").addClass("done");
          }
        },
        complete: function() {
          alert("complete");
        }
      });
    });
  </script>

  <link href="css/progressbar.css" rel="stylesheet" type="text/css" />

  </head>
  <body>
    <div id="progress" class="waiting">
  </body>
</html>

请注意,这是针对jQuery 2版本的,不支持Internet Explorer 8及更早版本。如果您需要支持旧版Internet Explorer,则应将目标设置为jQuery 1.10.2。

如果进度条未显示,但在动画完成后四秒钟后您确实收到了alert("complete"),那么很可能是您对CSS的引用有误(没有指向正确的位置或文件名拼写错误)。


1
我将alert("complete");替换为$("#progress").hide(); 工作完美!谢谢 - Moxet Khan
页面加载完成后,进度条仍然显示。 - Oracular Man

11

示例: Fiddle

请尝试以下代码。您必须将此文件运行在本地主机(本地服务器)中。

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $( document ).ready(function() {
        $({property: 0}).animate({property: 105}, {
            duration: 4000,
            step: function() {
                var _percent = Math.round(this.property);
                $('#progress').css('width',  _percent+"%");
                if(_percent == 105) {
                    $("#progress").addClass("done");
                }
            },
            complete: function() {
                alert('complete');
            }
        });
    });
</script>
<style>
    #progress {
        position: fixed;
        z-index: 2147483647;
        top: 0;
        left: -6px;
        width: 0%;
        height: 2px;
        background: #b91f1f;
        -moz-border-radius: 1px;
        -webkit-border-radius: 1px;
        border-radius: 1px;
        -moz-transition: width 500ms ease-out,opacity 400ms linear;
        -ms-transition: width 500ms ease-out,opacity 400ms linear;
        -o-transition: width 500ms ease-out,opacity 400ms linear;
        -webkit-transition: width 500ms ease-out,opacity 400ms linear;
        transition: width 500ms ease-out,opacity 400ms linear
    }
    #progress.done {
        opacity: 0
    }
    #progress dd,#progress dt {
        position: absolute;
        top: 0;
        height: 2px;
        -moz-box-shadow: #b91f1f 1px 0 6px 1px;
        -ms-box-shadow: #b91f1f 1px 0 6px 1px;
        -webkit-box-shadow: #b91f1f 1px 0 6px 1px;
        box-shadow: #b91f1f 1px 0 6px 1px;
        -moz-border-radius: 100%;
        -webkit-border-radius: 100%;
        border-radius: 100%
    }
    #progress dd {
        opacity: 1;
        width: 20px;
        right: 0;
        clip: rect(-6px,22px,14px,10px)
    }
    #progress dt {
        opacity: 1;
        width: 180px;
        right: -80px;
        clip: rect(-6px,90px,14px,-6px)
    }
    @-moz-keyframes pulse {
        30% {
            opacity: 1
        }
        60% {
            opacity: 0
        }
        100% {
            opacity: 1
        }
    }
    @-ms-keyframes pulse {
        30% {
            opacity: .6
        }
        60% {
            opacity: 0
        }
        100% {
            opacity: .6
        }
    }
    @-o-keyframes pulse {
        30% {
            opacity: 1
        }
        60% {
            opacity: 0
        }
        100% {
            opacity: 1
        }
    }
    @-webkit-keyframes pulse {
        30% {
            opacity: .6
        }
        60% {
            opacity: 0
        }
        100% {
            opacity: .6
        }
    }
    @keyframes pulse {
        30% {
            opacity: 1
        }
        60% {
            opacity: 0
        }
        100% {
            opacity: 1
        }
    }
    #progress.waiting dd,#progress.waiting dt {
        -moz-animation: pulse 2s ease-out 0s infinite;
        -ms-animation: pulse 2s ease-out 0s infinite;
        -o-animation: pulse 2s ease-out 0s infinite;
        -webkit-animation: pulse 2s ease-out 0s infinite;
        animation: pulse 2s ease-out 0s infinite
    }
</style>
<div id="progress" class="waiting">
    <dt></dt>
    <dd></dd>
</div>

或者:

只需将此文件上传到您的服务器,然后执行该文件。肯定可以正常工作。


1
我没有点踩,但需要提到的是,这个解决方案只能在页面加载时使用一次...它不适用于'ajax集成'。一个人需要在他们的ajax({xhr: <set here in function>});调用中手动设置'done'类。此外,需要一个无过渡样式,应禁用动画和过渡,以便#progress.css({width: <width>})(即将宽度重置为0%)不会导致隐藏的加载器显示并在一般情况下显示/转换重置加载器的其余部分。希望对你有所帮助。 - Rik
@NathanSrivi,能否请您给我提供一个jsfiddle链接,以便查看如何在页面中存在多个链接导致加载页面内容时使用它。谢谢。 - Mou

5
如果您想要一个类似于YouTube的加载器,用于您的AJAX应用程序,并且实际上代表了合法的页面加载进度,请考虑以下解决方案(基于Nathan Srivi的答案):
在您的`.ajax()`方法中:
$.ajax 
( 
  { 
...
    xhr: function() 
    { 
      var xhr = new window.XMLHttpRequest();

      //Upload progress
      xhr.upload.addEventListener
      (
        "progress",
        function( event)
        {
          if( event.lengthComputable )
          {
            var percentComplete = Math.round( ( ( event.loaded / event.total ) * 100 ) );

            // Do something with upload progress
            $( '#progress' ).css( { 'width':  percentComplete + '%' } );

            if( percentComplete == 100 )
            {
              $( '#progress' ).addClass( 'finished' );
              $( '#progress' ).delay( 500 ).queue
              (
                'fx',
                function( next )
                {
                  $( '#progress' ).addClass( 'notransition' );
                  $( this ).css( { width: '' } );
                  $( this ).removeClass( 'finished' );
                  next();
                }
              );
            }
          }
        },
        false
      );

      //Download progress
      xhr.addEventListener
      (
        "progress",
        function( event )
        {
          if( event.lengthComputable )
          {
            var percentComplete = Math.round( ( ( event.loaded / event.total ) * 100 ) );

            // Do something with upload progress
            $( '#progress' ).css( { 'width':  percentComplete + '%' } );

            if( percentComplete == 100 )
            {
              $( '#progress' ).addClass( 'finished' );
              $( '#progress' ).delay( 500 ).queue
              (
                'fx',
                function( next )
                {
                  $( '#progress' ).addClass( 'notransition' );
                  $( this ).css( { width: '' } );
                  $( this ).removeClass( 'finished' );
                  next();
                }
              );
            }
          }
        },
        false
      );

      return xhr;
    },
...
    success: function( data, textStatus, xhr )
    {
      ...
      // Reset our ajax loading progress bar
      $( '#progress' ).removeClass( 'notransition' );
      ...
    }

然后,在你的css中使用这个:

#progress {
  position: fixed;
  opacity: 1;
  z-index: 2147483647;
  top: 0;
  left: -6px;
  width: 0%;
  height: 2px;
  background: #b91f1f;
  -moz-border-radius: 1px;
  -webkit-border-radius: 1px;
  border-radius: 1px;
  -moz-transition: width 500ms ease-out,opacity 400ms linear;
  -ms-transition: width 500ms ease-out,opacity 400ms linear;
  -o-transition: width 500ms ease-out,opacity 400ms linear;
  -webkit-transition: width 500ms ease-out,opacity 400ms linear;
  transition: width 500ms ease-out,opacity 400ms linear;
}
#progress.finished {
  opacity: 0 !important;
}
#progress.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

#progress dd,#progress dt {
  position: absolute;
  top: 0;
  height: 2px;
  -moz-box-shadow: #b91f1f 1px 0 6px 1px;
  -ms-box-shadow: #b91f1f 1px 0 6px 1px;
  -webkit-box-shadow: #b91f1f 1px 0 6px 1px;
  box-shadow: #b91f1f 1px 0 6px 1px;
  -moz-border-radius: 100%;
  -webkit-border-radius: 100%;
  border-radius: 100%;
}
#progress dd {
  opacity: 1;
  width: 20px;
  right: 0;
  clip: rect(-6px,22px,14px,10px); 
}
#progress dt {
  opacity: 1;
  width: 180px;
  right: -80px;
  clip: rect(-6px,90px,14px,-6px);
}
@-moz-keyframes pulse {
  30% {
    opacity: 1
  }
  60% {
    opacity: 0
  }
  100% {
    opacity: 1
  }
}
@-ms-keyframes pulse {
  30% {
    opacity: .6
  }
  60% {
    opacity: 0
  }
  100% {
    opacity: .6
  }
}
@-o-keyframes pulse {
  30% {
    opacity: 1
  }
  60% {
    opacity: 0
  }
  100% {
    opacity: 1
  }
}
@-webkit-keyframes pulse {
  30% {
    opacity: .6
  }
  60% {
    opacity: 0
  }
  100% {
    opacity: .6
  }
}
@keyframes pulse {
  30% {
    opacity: 1
  }
  60% {
    opacity: 0
  }
  100% {
    opacity: 1
  }
}
#progress.waiting dd,#progress.waiting dt {
  -moz-animation: pulse 2s ease-out 0s infinite;
  -ms-animation: pulse 2s ease-out 0s infinite;
  -o-animation: pulse 2s ease-out 0s infinite;
  -webkit-animation: pulse 2s ease-out 0s infinite;
  animation: pulse 2s ease-out 0s infinite
}
#progress.notransition dd,#progress.notransition dt {
  -moz-animation: none !important;
  -ms-animation: none !important;
  -o-animation:  none !important;
  -webkit-animation:  none !important;
  animation:  none !important;
}

现在您应该拥有一个适用于每个AJAX操作的加载程序...并且真正能够表示已接收到响应的百分比,而不仅仅是在首次加载主页面时播放花哨的动画。
要使其在初始页面加载上运行(即它实际上没有显示合法的进度),请使用Nathan Srivi在上面提到的document.ready函数中的方法,并超出我已经提到的内容。
$( document ).ready(function() {
    $({property: 0}).animate({property: 105}, {
        duration: 4000,
        step: function() {
            var _percent = Math.round(this.property);
            $('#progress').css('width',  _percent+"%");
            if(_percent == 105) {
                $("#progress").addClass("done");
            }
        },
        complete: function() {
            alert('complete');
        }
    });
});

最后,您需要确保在向浏览器发送数据时包含“Content-Length”头信息,以便使此加载器正常工作……否则,event.lengthComputable 成员将会被解析为 false…此时进度条将无法加载。希望对您有所帮助,如有不一致之处,请随意编辑。

请您能否发布一个演示版本的代码,以便我可以运行并查看其工作原理。 - Mou
如何发送“Content-Length”头信息到浏览器? - Mou
好东西!#progress 中的 dddt 标签应该如何格式化?我不认为它们有任何必要的作用。 - Tim
@Tim,#progress dt#progress dd以及类似的CSS样式分别控制dd和dt标签的样式和格式。它们是脉冲效果的一部分。如果您想询问HTML的外观:<div id="progress" class="waiting"><dt></dt><dd></dd></div> - Rik
@Mou,“Content-Length”标头通常由Web服务器自动发送。当使用诸如Node.js之类的技术时,您可能需要发送响应的“长度”并手动设置Content-Length标头,但是如果使用反向代理,则正在使用的Web服务器可能会为您执行此操作(尽管在使用nginx通过反向代理时仍需发送标头)。我在mmogp.com上使用上述加载器。 - Rik

1

来自TalkersCode.com的代码和教程,http://talkerscode.com/webtricks/display-progress-bar-while-page-loads-using-jquery.php中有详细说明。

function check_element(ele)
{
 var all = document.getElementsByTagName("*");
 var totalele=all.length;
 var per_inc=100/all.length;

 if($(ele).on())
 {
  var prog_width=per_inc+Number(document.getElementById("progress_width").value);
  document.getElementById("progress_width").value=prog_width;
  $("#bar1").animate({width:prog_width+"%"},10,function(){
  if(document.getElementById("bar1").style.width=="100%")
  {
    $(".progress").fadeOut("slow");
  }         
  });
 }

 else   
 {
  set_ele(ele);
 }
}

0

你可以在 GitHub 上获取进度条插件。

https://github.com/shashibeit/progressbar

你需要在你的项目中包含并调用以下函数

Progress.start(); Progress.go(20); Progress.go(30); Progress.go(80); Progress.go(100); Progress.complete();


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