Joe278
Joe278

Reputation: 105

Progress bar - jQuery to Pure Vanilla JS

I am trying to convert this small script to a pure vanilla JS.

The plain JS values are not calculated correctly.

What do I need to get to calculate the same value as in the jQuery version?

Pleaset scroll down in the jQuery fiddle to see what l mean.

$(document).scroll(function() {
    var progressBar = $('progress'),
        docHeight = $(this).height(),
        winHeight = $(window).height(),
        max = docHeight - winHeight,
        value = $(window).scrollTop();
    progressBar.attr('max', max);
    progressBar.attr('value', value);
});

DEMO jQuery

And below, my pure JS which doesn't work :

var progressBar = function() {
    var myBar = document.querySelector('progress'),
        docHeight = document.clientHeight,
        winHeight = window.clientHeight,
        max = docHeight - winHeight,
        value = window.scrollY;
    myBar.setAttribute('data-max', myBar.getAttribute('max'));
    myBar.setAttribute('max', max);
    myBar.setAttribute('data-value', myBar.getAttribute('value'));
    myBar.setAttribute('value', value);
};
document.addEventListener('scroll', progressBar);
window.addEventListener('resize', progressBar);

My attempt in vanilla

Thank you!!

Upvotes: 4

Views: 736

Answers (2)

crenshaw-dev
crenshaw-dev

Reputation: 8412

You'll need to use different properties to access the document and window heights.

  1. document.clientHeight should be document.body.clientHeight. The clientHeight property is designed to return the calculated heights of HTML elements. Using the body element fits within that design.

  2. window.clientHeight should be window.innerHeight. Since window isn't an HTML element, it has its own height properties.

I also simplified the progress bar attribute-setting logic. Unless you have some external requirement to set the data-max and data-value attributes, you can remove those lines. If you do need to set those attributes, you can use the dataset property.

var progressBar = function() {
    var myBar = document.querySelector('progress'),
        docHeight = document.body.clientHeight,
        winHeight = window.innerHeight,
        max = docHeight - winHeight,
        value = window.scrollY;
    myBar.setAttribute('max', max);
    myBar.setAttribute('value', value);
};
document.addEventListener('scroll', progressBar);
window.addEventListener('resize', progressBar);

See JSFiddle.

Upvotes: 5

Sean
Sean

Reputation: 1289

The clientHeight property doesn't exist on window or document. If you have a look at the JQuery docs:

  • $(window).height() returns height of browser viewport
  • $(document).height() returns the height of HTML document

There already a great answer on StackOverflow explaining the different ways to get the height. Looking at the JQuery source, the height of the window uses window.innerHeight. For the document it's using the max of:

  • document.body.scrollHeight
  • document.body.offsetHeight
  • document.documentElement.clientHeight

Putting it all together, it works AOK: https://jsfiddle.net/pd3dtvxn/7/

Upvotes: 3

Related Questions