YouTube-like progress bar

2019-01-30 05:14发布

问题:

I am trying to make a YouTube-like progress bar. The bar should load at the page startup. I have tried this so far. Here is the code of my script

$({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');
    }
});

I am also including the jsFiddle of the same, http://jsfiddle.net/ajaSB/3/.

In this jsfiddle, the progress bar appears, but when I use the same code in my IDE and run the file no progress bar appears. What am I doing wrong? Or if there is another way to get the bar?

回答1:

Here is example of a complete HTML page including reference to the jQuery library.

Although it will mostly work without, you should wrap your code in a $(document).ready(...) so that you are sure all required resources are loaded before you run the code.

<!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>

Note that this targets version 2 of jQuery, which does not support Internet Explorer 8 and earlier. If you need support for old Internet Explorer versions, you should target jQuery 1.10.2 instead.

If the progress bar does not show, but you do get the alert("complete") after four seconds when the animation should be finished, it is likely that your reference to the CSS is wrong (not pointing to the right place, or misspelled file name).



回答2:

NProgress.js is a very cool and simple library. The Git repository is here. It has an MIT License.



回答3:

Demo : Fiddle

Try the following code. You must run this file into your localhost (local server).

<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>

Or:

Just upload this file to your server, and then you execute the file. Definitely it works.



回答4:

LoadingBar.js: Adding a YouTube-Like loading bar to your website

YouTube has recently added a red loading bar at the top of the page to indicate that the next page is loading. You may wonder why they didn’t rely on the browser’s loading bar. That’s because the next page is being loaded with Ajax which doesn’t trigger the normal page load mechanism. That’s why the browser didn’t pick it up. As some of you may know, loading the entire content via Ajax can make your website load faster than the normal way.

That’s because all the static content is left unchanged, and only the dynamic content is being loaded. That way you don’t have to keep asking the server for static content that will never change over and over creating an overload.

DEMO

DOWNLOAD

Create a YouTube-Like loading bar for the web

As mentioned in a blog post by Dmitry Fadeyev over at UsabilityPost, many developers are integrating this UI pattern to their websites more and more. Today I decided to build a jQuery plugin that will let you add a loading bar to any Ajax links on your website. Let me show you how it works.

Basic Usage

HTML markup

<a href="<<URL>>" class="ajax-call">..</a>
<div id="loadingbar-frame"></div>

JavaScript

$(".ajax-call").loadingbar({
  target: "#loadingbar-frame",
  replaceURL: false,
  direction: "right",

  /* Default Ajax parameters.  */
  async: true, 
  complete: function(xhr, text) {},
  cache: true,
  error: function(xhr, text, e) {},
  global: true,
  headers: {},
  statusCode: {},
  success: function(data, text, xhr) {},
  dataType: "html",
  done: function(data) {}
});

CSS customization

#loadingbar {
    background: YOUR COLOR;
}

#loadingbar dd, #loadingbar dt {
  -moz-box-shadow: YOUR COLOR 1px 0 6px 1px;
  -ms-box-shadow: YOUR COLOR 1px 0 6px 1px;
  -webkit-box-shadow: YOUR COLOR 1px 0 6px 1px;
  box-shadow: YOUR COLOR 1px 0 6px 1px;
}

And that’s it. You will now have an awesome loading bar for all your Ajax calls. I hope you enjoy this :)



回答5:

If you want a 'youtube-like' loader for your AJAX application that actually represents legitimate page loading progress, consider the following solution (based on Nathan Srivi's answer):

In your .ajax() method:

$.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' );
      ...
    }

Then, in your css; use this:

#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;
}

And now you should have a loader that works for each AJAX operation...and really works to represent the true percentage of how much of the response has been received, instead of just playing a fancy animation when you first load the main page.

To make it operational on the initial page load (i.e. its not actually displaying legitimate progress), use the method that Nathan Srivi mentions in a document.ready function above and beyond what I already mentioned:

$( 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');
        }
    });
});

Lastly,

You will need to ensure that 'Content-Length' headers are being sent to the browser in order for a loader of this design to work correctly...otherwise the event.lengthComputable member resolves to false...and no progress bar will load.

HTH, feel free to edit inconsistencies.



回答6:

An image loading demo by Nprogress may help.



回答7:

Code from TalkersCode.com and tutorial here 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);
 }
}


回答8:

You can get the plugin for the progress bar
I have published it on GitHub

https://github.com/shashibeit/progressbar

you will need to include in your project and call the below functions

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