How can I check if a scrollbar is visible?

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

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

For example:

HTML

19条回答
  •  长发绾君心
    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;
    }
    

提交回复
热议问题