34

I am trying to process some code based on the 'document.documentElement.scrollTop' value. It returns '348' in FF and IE but in Chrome it returns '0'. Do i need to do anything to overcome this issue?

FF:

>>> document.documentElement.scrollTop
342

Chrome:

document.documentElement.scrollTop
0
RGR
  • 1,521
  • 2
  • 22
  • 36

6 Answers6

51

The standards-based way of getting the scroll is window.scrollY. This is supported by Chrome, Firefox, Opera, Safari and IE Edge or later. If you only support these browsers, you should go with this property.

IE >= 9 supports a similar property window.pageYOffset, which for the sake of compatibility returns the same as window.scrollY in recent browsers, though it may perhaps be deprecated at some point.

The problem with using document.documentElement.scrollTop or document.body.scrollTop is that the scroll needn't be defined on either of these. Chrome and Safari define their scroll on the <body> element whilst Firefox defines it on the <html> element returned by document.documentElement, for example. This is not standardized, and could potentially change in future versions of the browsers. However, if the scrollY or pageYOffset are not present, this is the only way to get the scroll.

TL;DR:

window.scrollY || window.pageYOffset || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0)

jazmit
  • 5,170
  • 1
  • 29
  • 36
  • returns `NaN` in chrome 46 – Quamis Dec 09 '15 at 14:44
  • Works fine for me on chrome 47... Does your problem occur on any particular site or all sites? – jazmit Dec 11 '15 at 14:13
  • @jazmit: what is the usage of this part of the condition document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0) – albert Jegani Jan 18 '16 at 10:10
  • The scroll can be defined on either `document.body` or `document.documentElement`. Theoretically, it could be defined on both, so we use addition to combine the scrolls. `documentElement` may not be defined at all, thus the || 0 default. – jazmit Jan 18 '16 at 10:27
  • if its defined mean? sure we know that the document.body.scrollTop and document.documentElement.scrollTop is not going to present in same time. so y we need the concatenation here...i m not able to understand – albert Jegani Jan 18 '16 at 13:21
  • y dont we give like this window.scrollY || window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop – albert Jegani Jan 18 '16 at 13:26
  • how does scrollY compare to `document.scrollingElement.scrollTop`? – Janus Troelsen Feb 08 '17 at 18:46
19

Try this

window.pageYOffset || document.documentElement.scrollTop
Nick Salloum
  • 2,158
  • 12
  • 13
  • 1
    Fun fact: this doesn't always work in a WebView in Windows Phone. Esoteric edge case, but something I just slammed into. Those numbers are sometimes different, emphasis on the sometimes, and the pageYOffset appears to be wrong when they are. – Aaron Apr 26 '14 at 01:55
  • Thanks pal, that fixed an issue I had with Safari – AugustoM Sep 09 '19 at 16:26
3

You can just use the following codes to fix that bug!

let scrollHeight = document.body.scrollTop || document.documentElement.scrollTop;
console.log(`scrollHeight = ${scrollHeight}`);


/*

this comment just using for testing the scroll height!

but in this iframe, it doesn't work at all!

So, you can try it out using Chrome console!

*/

document.body.scrollTop;
// For Chrome, Safari and Opera
document.documentElement.scrollTop;
// Firefox and IE places the overflow at the level, unless else is specified.
Therefore, we use the documentElement property for these two browsers

reference links:
http://www.w3schools.com/jsref/prop_element_scrolltop.asp

https://drafts.csswg.org/cssom-view/#dom-element-scrolltop

https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop

xgqfrms
  • 10,077
  • 1
  • 69
  • 68
3

Use window.scrollY where possible, it's designed to be consistent across browsers. If you need to support IE, then I'd recommend the following to only use window.scrollY if it's available:

typeof window.scrollY === "undefined" ? window.pageYOffset : window.scrollY

window.scrollY will be evaluated as false if it returns 0, so doing window.scrollY || window.pageYOffset would technically check window.pageYOffset whenever window.scrollY were 0, which obviously isn't ideal if window.pageYOffset did not also equal 0.

Also note that if you need to get the scroll value frequently (every frame/every scroll) as is often the case, you might want to check if window.scrollY is defined beforehand. I like to use this small helper function I wrote to do exactly that, along with using requestAnimationFrame - it should work in IE10 and up.

function registerScrollHandler (callback) {
    "use strict"

    var useLegacyScroll = typeof window.scrollY === "undefined",
        lastX = useLegacyScroll ? window.pageXOffset : window.scrollX,
        lastY = useLegacyScroll ? window.pageYOffset : window.scrollY

    function scrollHandler () {
        // get the values using legacy scroll if we need to
        var thisX = useLegacyScroll ? window.pageXOffset : window.scrollX,
            thisY = useLegacyScroll ? window.pageYOffset : window.scrollY

        // if either the X or Y scroll position changed
        if (thisX !== lastX || thisY !== lastY) {
            callback(thisX, thisY)

            // save the new position
            lastX = thisX
            lastY = thisY
        }

        // check again on the next frame
        window.requestAnimationFrame(scrollHandler)
    }

    scrollHandler()
}

Use the function like this:

registerScrollHandler(function (x, y) {
    /* your code here :) */
    console.log("Scrolled the page", x, y)
})
Xenxier
  • 431
  • 4
  • 7
2

You can use this function document.body.getBoundingClientRect() and it returns this object {x: 0, y: 0, width: 1903, height: 2691.5625, top: 0, …}; in this object you can access body top document.body.getBoundingClientRect().top

0

This happens when using the Safari version 13 or the lower version. Please update your Safari browser to 14 or higher.

Gayan Chinthaka
  • 521
  • 6
  • 5