How can I check if a scrollbar is visible?

后端 未结 19 2604
情话喂你
情话喂你 2020-11-22 14:39

Is it possible to check the overflow:auto of a div?

For example:

HTML

相关标签:
19条回答
  • 2020-11-22 15:28

    You can do this using a combination of the Element.scrollHeight and Element.clientHeight attributes.

    According to MDN:

    The Element.scrollHeight read-only attribute is a measurement of the height of an element's content, including content not visible on the screen due to overflow. The scrollHeight value is equal to the minimum clientHeight the element would require in order to fit all the content in the viewpoint without using a vertical scrollbar. It includes the element padding but not its margin.

    And:

    The Element.clientHeight read-only property returns the inner height of an element in pixels, including padding but not the horizontal scrollbar height, border, or margin.

    clientHeight can be calculated as CSS height + CSS padding - height of horizontal scrollbar (if present).

    Therefore, the element will display a scrollbar if the scroll height is greater than the client height, so the answer to your question is:

    function scrollbarVisible(element) {
      return element.scrollHeight > element.clientHeight;
    }
    
    0 讨论(0)
  • 2020-11-22 15:29

    The solutions provided above will work in the most cases, but checking the scrollHeight and overflow is sometimes not enough and can fail for body and html elements as seen here: https://codepen.io/anon/pen/EvzXZw

    1. Solution - Check if the element is scrollable:

    function isScrollableY (element) {
      return !!(element.scrollTop || (++element.scrollTop && element.scrollTop--));
    }
    

    Note: elements with overflow: hidden are also treated as scrollable (more info), so you might add a condition against that too if needed:

    function isScrollableY (element) {
        let style = window.getComputedStyle(element);
        return !!(element.scrollTop || (++element.scrollTop && element.scrollTop--)) 
               && style["overflow"] !== "hidden" && style["overflow-y"] !== "hidden";
    }
    

    As far as I know this method only fails if the element has scroll-behavior: smooth.

    Explanation: The trick is, that the attempt of scrolling down and reverting it won't be rendered by the browser. The topmost function can also be written like the following:

    function isScrollableY (element) {
      // if scrollTop is not 0 / larger than 0, then the element is scrolled and therefore must be scrollable
      // -> true  
      if (element.scrollTop === 0) {
        // if the element is zero it may be scrollable  
        // -> try scrolling about 1 pixel
        element.scrollTop++;
        // if the element is zero then scrolling did not succeed and therefore it is not scrollable 
        // -> false  
        if (element.scrollTop === 0) return false;
        // else the element is scrollable; reset the scrollTop property
        // -> true
        element.scrollTop--;
      }
      return true;
    }

    2. Solution - Do all the necessary checks:

    function isScrollableY (element) {
      const style = window.getComputedStyle(element);
      
      if (element.scrollHeight > element.clientHeight &&
          style["overflow"] !== "hidden" && style["overflow-y"] !== "hidden" &&
          style["overflow"] !== "clip" && style["overflow-y"] !== "clip"
      ) {
        if (element === document.scrollingElement) return true;
        else if (style["overflow"] !== "visible" && style["overflow-y"] !== "visible") {
          // special check for body element (https://drafts.csswg.org/cssom-view/#potentially-scrollable)
          if (element === document.body) {
            const parentStyle = window.getComputedStyle(element.parentElement);
            if (parentStyle["overflow"] !== "visible" && parentStyle["overflow-y"] !== "visible" &&
                parentStyle["overflow"] !== "clip" && parentStyle["overflow-y"] !== "clip"
            ) {
              return true;
            }
          }
          else return true;
        }
      }
      
      return false;
    }
    
    0 讨论(0)
  • 2020-11-22 15:30

    The first solution above works only in IE The second solution above works only in FF

    This combination of both functions works in both browsers:

    //Firefox Only!!
    if ($(document).height() > $(window).height()) {
        // has scrollbar
        $("#mtc").addClass("AdjustOverflowWidth");
        alert('scrollbar present - Firefox');
    } else {
        $("#mtc").removeClass("AdjustOverflowWidth");
    }
    
    //Internet Explorer Only!!
    (function($) {
        $.fn.hasScrollBar = function() {
            return this.get(0).scrollHeight > this.innerHeight();
        }
    })(jQuery);
    if ($('#monitorWidth1').hasScrollBar()) {
        // has scrollbar
        $("#mtc").addClass("AdjustOverflowWidth");
        alert('scrollbar present - Internet Exploder');
    } else {
        $("#mtc").removeClass("AdjustOverflowWidth");
    }​
    
    • Wrap in a document ready
    • monitorWidth1 : the div where the overflow is set to auto
    • mtc : a container div inside monitorWidth1
    • AdjustOverflowWidth : a css class applied to the #mtc div when the Scrollbar is active *Use the alert to test cross browser, and then comment out for final production code.

    HTH

    0 讨论(0)
  • 2020-11-22 15:30

    Works on Chrome, Edge, Firefox and Opera, at least in the newer versions.

    Using JQuery...

    Setup this function to fix the footer:

    function fixFooterCaller()
    {
        const body = $('body');
        const footer = $('body footer');
    
        return function ()
        {
            // If the scroll bar is visible
            if ($(document).height() > $(window).height())
            {
                // Reset
                footer.css('position', 'inherit');
                // Erase the padding added in the above code
                body.css('padding-bottom', '0');
            }
            // If the scrollbar is NOT visible
            else
            {
                // Make it fixed at the bottom
                footer.css('position', 'fixed');
                // And put a padding to the body as the size of the footer
                // This makes the footer do not cover the content and when
                // it does, this event fix it
                body.css('padding-bottom', footer.outerHeight());
            }
        }
    }
    

    It returns a function. Made this way just to set the body and footer once.

    And then, set this when the document is ready.

    $(document).ready(function ()
    {
        const fixFooter = fixFooterCaller();
    
        // Put in a timeout call instead of just call the fixFooter function
        // to prevent the page elements needed don't be ready at this time
        setTimeout(fixFooter, 0);
        // The function must be called every time the window is resized
        $(window).resize(fixFooter);
    });
    

    Add this to your footer css:

    footer {
        bottom: 0;
    }
    
    0 讨论(0)
  • 2020-11-22 15:31

    Most of the answers presented got me close to where I needed to be, but not quite there.

    We basically wanted to assess if the scroll bars -would- be visible in a normal situation, by that definition meaning that the size of the body element is larger than the view port. This was not a presented solution, which is why I am submitting it.

    Hopefully it helps someone!

    (function($) {
        $.fn.hasScrollBar = function() {
            return this.get(0).scrollHeight > $(window).height();
        }
    })(jQuery);
    

    Essentially, we have the hasScrollbar function, but returning if the requested element is larger than the view port. For view port size, we just used $(window).height(). A quick compare of that against the element size, yields the correct results and desirable behavior.

    0 讨论(0)
  • 2020-11-22 15:32

    a little plugin for it.

    (function($) {
        $.fn.hasScrollBar = function() {
            return this.get(0).scrollHeight > this.height();
        }
    })(jQuery);
    

    use it like this,

    $('#my_div1').hasScrollBar(); // returns true if there's a `vertical` scrollbar, false otherwise..
    

    tested working on Firefox, Chrome, IE6,7,8

    but not working properly on body tag selector

    demo


    Edit

    I found out that when you have horizontal scrollbar that causes vertical scrollbar to appear, this function does not work....

    I found out another solution... use clientHeight

    return this.get(0).scrollHeight > this.get(0).clientHeight;
    
    0 讨论(0)
提交回复
热议问题