简体   繁体   中英

Change Progress Bar Value based on Scrolling

I would like to be able to make my progress bar increase, based on how far I've scrolled and how much is left.

I've tried this: jsFiddle and it doesn't seem to work, I based my script off someone's script that made a block move horizontally based on scroll %.

My code:

<progress id="progressbar" value="0" max="100"></progress>
<br />
<br />
<br />
Lorem<br />
Ipsum<br />
Dolor<br />
.
.
.
.

JS:

$(document).ready(function () {
    $(window).scroll(function () {
        var s = $(this).scrollTop(),
            d = $(document).height(),
            scrollPercent = (s / d);
        var position = (scrollPercent);
        $("#progressbar").progressbar('value', position);
    });
});

Working DEMO

Try this

$(window).scroll(function () {
  var s = $(window).scrollTop(),
        d = $(document).height(),
        c = $(window).height();
        scrollPercent = (s / (d-c)) * 100;
        var position = scrollPercent;

   $("#progressbar").attr('value', position);

});

Hope this helps, Thank you

The logic is like this

totalValue  = (documentHeight - windowHeight);
currntValue = scrolledValue;
percentage =  (currntValue/ totalValue  ) * 100

http://jsfiddle.net/PvVdq/71/

   $(document).ready(function () {
    $(window).scroll(function () {
        var s = $(this).scrollTop(),
            d = $(document).height()-$(window).height(),
            scrollPercent = (s / d)*100;       
        $("#progressbar").attr('value', scrollPercent);
     });
 });

I would suggest making the max value of the progress bar dynamic according to the size of the page.

Change the HTML for your progress bar to this.

<progress id="progressbar" value="0"></progress>

This is how your jQuery would look.

$(document).ready(function () {
    $(window).scroll(function () {
        var s = $(document).scrollTop(),
            d = $(document).height() - $(window).height();          
        $("#progressbar").attr('max', d);
        $("#progressbar").attr('value', s);
     });
 });

This eliminates the need for hacky calculations and also makes the progress bar dynamic in case of longer or shorter pages.

Working DEMO

To get the current scrolling ratio, you should check if your document has a scrollableHeight first. In this special case I choosed to return 0 . Next calculation is the same as above.

/**
 * @returns number
 */
function scrollYProgression() {
    const scrollableHeight = window.document.body.scrollHeight - window.innerHeight;
    if (scrollableHeight <= 0) return 0;

    return window.scrollY / scrollableHeight;
}

Bundled up with jQuery :

$(window).scroll(() => {
    $('#progressbar')
        .attr('value', scrollYProgression() * 100);
});

Beware when you listen to scroll events! This can be really heavy and you really need it at most once per repaint. You can check the window.requestAnimationFrame to prevent massive call to your method (max 60/s).

Regarding scroll event listeners: http://www.html5rocks.com/en/tutorials/speed/animations

EDIT :

Without jQuery and using window.requestAnimationFrame to limite trigger rate to 60/s

/** @return number */
function scrollYProgression() {
    const scrollableHeight = window.document.body.scrollHeight - window.innerHeight;
    if (scrollableHeight <= 0) return 0;

    return window.scrollY / scrollableHeight;
}

/**
 *  @return void
 *  @description DOM element manipulation
 */
function scrollHandler() {
    const progress = scrollYProgression();
    const bar = document.getElementById('progressbar');
    bar.setAttribute('value', progress * 100);
}

/** Start listening */
window.addEventListener('scroll', function(ev){
    window.requestAnimationFrame(scrollHandler);
}, { passive: true });

In the modern web this can be done fairly easily in vanilla js (basic approach pulled from this article ):

 var progressBar = document.querySelector('progress'); var winheight, docheight, trackLength, throttlescroll; function getDocHeight() { var D = document; return Math.max( D.body.scrollHeight, D.documentElement.scrollHeight, D.body.offsetHeight, D.documentElement.offsetHeight, D.body.clientHeight, D.documentElement.clientHeight ); } function getMeasurements() { winheight = window.innerHeight || (document.documentElement || document.body).clientHeight; docheight = getDocHeight(); trackLength = docheight - winheight } function update() { var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop var pctScrolled = scrollTop / trackLength * 100; var wholePct = Math.floor(pctScrolled); progressBar.value = pctScrolled; } getMeasurements(); window.addEventListener('scroll', update, false); window.addEventListener("resize", getMeasurements, false); 
 progress { position: fixed; top: 0; left: 0; /* Reset the default appearance */ -webkit-appearance: none; appearance: none; } 
 <progress max="100"></progress> <p>Purr when being pet give me some of your food give me some of your food give me some of your food meh, i don't want it disappear for four days and return home with an expensive injury; bite the vet chew iPad power cord, but human give me attention meow or scream for no reason at 4 am. Lick sellotape hiss and stare at nothing then run suddenly away fall over dead (not really but gets sypathy) but sit in a box for hours, destroy the blinds. Meow all night having their mate disturbing sleeping humans and sometimes switches in french and say "miaou" just because well why not and pooping rainbow while flying in a toasted bread costume in space. Refuse to leave cardboard box eat from dog's food purr while eating. Leave hair everywhere lick master's hand at first then bite because im moody give attitude. </p> <p>Walk on car leaving trail of paw prints on hood and windshield attack the child so lick arm hair so relentlessly pursues moth, yet man running from cops stops to pet cats, goes to jail. Meow in empty rooms cough furball so give me some of your food give me some of your food give me some of your food meh, i don't want it fish i must find my red catnip fishy fish jumps off balcony gives owner dead mouse at present then poops in litter box snatches yarn and fights with dog cat chases laser then plays in grass finds tiny spot in cupboard and sleeps all day jumps in bathtub and meows when owner fills food dish the cat knocks over the food dish cat slides down the water slide and into pool and swims even though it does not like water pelt around the house and up and down stairs chasing phantoms so pee in the shoe. Munch, munch, chomp, chomp. Licks paws chase red laser dot or tuxedo cats always looking dapper meow i like frogs and 0 gravity or groom yourself 4 hours - checked, have your beauty sleep 18 hours - checked, be fabulous for the rest of the day - checked. Loves cheeseburgers. Toilet paper attack claws fluff everywhere meow miao french ciao litterbox play riveting piece on synthesizer keyboard put butt in owner's face step on your keyboard while you're gaming and then turn in a circle attack the dog then pretend like nothing happened. </p> 

However, it's probably best to limit how much the scroll function is ran by a requestAnimationFrame , in which case it's a little more complex:

 var progressBar = document.querySelector('progress'), ticking = false; var winheight, docheight, trackLength, throttlescroll; function getDocHeight() { var D = document; return Math.max( D.body.scrollHeight, D.documentElement.scrollHeight, D.body.offsetHeight, D.documentElement.offsetHeight, D.body.clientHeight, D.documentElement.clientHeight ); } function getMeasurements() { winheight = window.innerHeight || (document.documentElement || document.body).clientHeight; docheight = getDocHeight(); trackLength = docheight - winheight } function requestTick() { if(!ticking) { requestAnimationFrame(update); ticking = true; } } function update() { var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop var pctScrolled = scrollTop / trackLength * 100; var wholePct = Math.floor(pctScrolled); progressBar.value = pctScrolled; ticking = false; } getMeasurements(); window.addEventListener('scroll', requestTick, false); window.addEventListener("resize", getMeasurements, false); 
 progress { position: fixed; top: 0; left: 0; /* Reset the default appearance */ -webkit-appearance: none; appearance: none; } 
 <progress max="100" value="0"></progress> <p>Purr when being pet give me some of your food give me some of your food give me some of your food meh, i don't want it disappear for four days and return home with an expensive injury; bite the vet chew iPad power cord, but human give me attention meow or scream for no reason at 4 am. Lick sellotape hiss and stare at nothing then run suddenly away fall over dead (not really but gets sypathy) but sit in a box for hours, destroy the blinds. Meow all night having their mate disturbing sleeping humans and sometimes switches in french and say "miaou" just because well why not and pooping rainbow while flying in a toasted bread costume in space. Refuse to leave cardboard box eat from dog's food purr while eating. Leave hair everywhere lick master's hand at first then bite because im moody give attitude. </p> <p>Walk on car leaving trail of paw prints on hood and windshield attack the child so lick arm hair so relentlessly pursues moth, yet man running from cops stops to pet cats, goes to jail. Meow in empty rooms cough furball so give me some of your food give me some of your food give me some of your food meh, i don't want it fish i must find my red catnip fishy fish jumps off balcony gives owner dead mouse at present then poops in litter box snatches yarn and fights with dog cat chases laser then plays in grass finds tiny spot in cupboard and sleeps all day jumps in bathtub and meows when owner fills food dish the cat knocks over the food dish cat slides down the water slide and into pool and swims even though it does not like water pelt around the house and up and down stairs chasing phantoms so pee in the shoe. Munch, munch, chomp, chomp. Licks paws chase red laser dot or tuxedo cats always looking dapper meow i like frogs and 0 gravity or groom yourself 4 hours - checked, have your beauty sleep 18 hours - checked, be fabulous for the rest of the day - checked. Loves cheeseburgers. Toilet paper attack claws fluff everywhere meow miao french ciao litterbox play riveting piece on synthesizer keyboard put butt in owner's face step on your keyboard while you're gaming and then turn in a circle attack the dog then pretend like nothing happened. </p> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM