Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if "html" or "body" scrolls the window

The code below is used to find the element that can be scrolled (body or html) via javascript.

    var scrollElement = (function (tags) {
        var el, $el, init;
        // iterate through the tags...
        while (el = tags.pop()) {
            $el = $(el);
            // if the scrollTop value is already > 0 then this element will work
            if ( $el.scrollTop() > 0){
                return $el;
            }
            // if scrollTop is 0 try to scroll.
            else if($el.scrollTop( 1 ).scrollTop() > 0) {
                // if that worked reset the scroll top and return the element
                return $el.scrollTop(0);
            }
        }
        return $();
    } (["html", "body"]));

    // do stuff with scrollElement...like:
    // scrollElement.animate({"scrollTop":target.offset().top},1000);

This code works perfectly when the height of the document is greater than the height of the window. However, when the height of the document is the same or less than the window the method above will not work because scrollTop() will always be equal to 0. This becomes a problem if the DOM is updated and the height of the document grows beyond the height of the window after the code runs.

Also, I generally don't wait until document.ready to set up my javascript handlers (this generally works). I could append a tall div to the body temporarily to force the method above to work BUT that would require the document to be ready in IE (you can't add a node to the body element before the tag is closed). For more on the document.ready "anti-pattern" topic read this.

So, I'd love to find a solution that finds the scrollable element even when the document is short. Any ideas?

like image 886
David Murdoch Avatar asked May 14 '10 19:05

David Murdoch


1 Answers

Its been about 5 years since I asked this....but better late than never!

document.scrollingElement is now part of the CSSOM spec, but has little to no real-world browser implementation at this point (April 2015). However, you can still find the element...

By using this polyfill by Mathias Bynens and Diego Perini.

Which implements this basic solution by Diego Perini (The above polyfill is better and CSSOM compliant, so you should probably use that.):

/*
 * How to detect which element is the scrolling element in charge of scrolling the viewport:
 *
 * - in Quirks mode the scrolling element is the "body"
 * - in Standard mode the scrolling element is the "documentElement"
 *
 * webkit based browsers always use the "body" element, disrespectful of the specifications:
 *
 *  http://dev.w3.org/csswg/cssom-view/#dom-element-scrolltop
 *
 * This feature detection helper allow cross-browser scroll operations on the viewport,
 * it will guess which element to use in each browser both in Quirk and Standard modes.
 * See how this can be used in a "smooth scroll to anchors references" example here:
 *
 *  https://dl.dropboxusercontent.com/u/598365/scrollTo/scrollTo.html
 *
 * It is just a fix for possible differences between browsers versions (currently any Webkit).
 * In case the Webkit bug get fixed someday, it will just work if they follow the specs. Win !
 *
 * Author: Diego Perini
 * Updated: 2014/09/18
 * License: MIT
 *
 */
function getScrollingElement() {
  var d = document;
  return  d.documentElement.scrollHeight > d.body.scrollHeight &&
          d.compatMode.indexOf('CSS1') == 0 ?
          d.documentElement :
          d.body;
}

— getScrollingElement.js

like image 86
David Murdoch Avatar answered Sep 17 '22 20:09

David Murdoch