4

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

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Joe278
  • 105
  • 1
  • 7
  • `my pure JS who doesn't work` What doesn't work? Do you get errors? If so, what errors? try and give as much information as possible without asking people to go off site to look at your code. Better still, make a code snippet on here. – StudioTime Apr 28 '18 at 17:04
  • @DarrenSweeney The values are not the same. Look at the demo to see the red line progressing in the jQuery but toggles in the plain JS one. I assume all is needed is to correctly get the scroll height – mplungjan Apr 28 '18 at 17:06
  • @mplungjan I didn't even look tbh - I wanted to try encourage to use code snippet here instead - but yeah, you;re right by the looks of it – StudioTime Apr 28 '18 at 17:09
  • 1
    @DarrenSweeney I normally would agree on the encouragement, but actually the jsfiddles tell it all and the code here is sufficient to the knowledgable scripter to tell what is missing – mplungjan Apr 28 '18 at 17:10
  • Yep l don't know how catch document's and window's height... Do you have a right way? – Joe278 Apr 28 '18 at 17:17

2 Answers2

5

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.

crenshaw-dev
  • 7,504
  • 3
  • 45
  • 81
3

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/

Sean
  • 1,279
  • 9
  • 17