如何检查滚动条是否可见?

时间:2011-01-27 09:03:53

标签: javascript jquery scroll overflow

是否可以检查div的overflow:auto

例如:

HTML

<div id="my_div" style="width: 100px; height:100px; overflow:auto;" class="my_class"> 
  * content
</div>

JQUERY

$('.my_class').live('hover', function (event)
{
    if (event.type == 'mouseenter')
    {
         if( ...  if scrollbar visible ? ... )
         {
            alert('true'):
         }
         else
         {
            alert('false'):
         }
    }

});

有时内容很短(没有滚动条),有时很长(滚动条可见)。

19 个答案:

答案 0 :(得分:357)

它的一个小插件。

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

像这样使用它,

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

在Firefox,Chrome,IE6,7,8上进行了测试。

但在body代码选择器

上无法正常工作

demo


修改

我发现当你有水平滚动条导致垂直滚动条出现时,这个功能不起作用....

我找到了另一个解决方案......使用clientHeight

return this.get(0).scrollHeight > this.get(0).clientHeight;

答案 1 :(得分:50)

也许是一个更简单的解决方案。

if ($(document).height() > $(window).height()) {
    // scrollbar
}

答案 2 :(得分:41)

我应该改变Reigel所说的一点:

(function($) {
    $.fn.hasScrollBar = function() {
        return this.get(0) ? this.get(0).scrollHeight > this.innerHeight() : false;
    }
})(jQuery);

innerHeight计算控件的高度及其顶部和底部填充

答案 3 :(得分:31)

您可以结合使用Element.scrollHeightElement.clientHeight属性来执行此操作。

根据MDN:

  

Element.scrollHeight 只读属性是元素内容高度的度量,包括因溢出而在屏幕上不可见的内容。 scrollHeight值等于元素所需的最小clientHeight,以便在不使用垂直滚动条的情况下拟合视点中的所有内容。它包含元素填充但不包括其边距。

  

Element.clientHeight 只读属性返回元素的内部高度(以像素为单位),包括填充,但不包括水平滚动条高度,边框或边距。

     

clientHeight可以计算为CSS高度+ CSS填充 - 水平滚动条的高度(如果存在)。

因此,如果滚动高度大于客户端高度,该元素将显示滚动条,因此您的问题的答案是:

function scrollbarVisible(element) {
  return element.scrollHeight > element.clientHeight;
}

答案 4 :(得分:23)

这扩展了@Reigel的答案。它将返回水平或垂直滚动​​条的答案。

(function($) {
    $.fn.hasScrollBar = function() {
        var e = this.get(0);
        return {
            vertical: e.scrollHeight > e.clientHeight,
            horizontal: e.scrollWidth > e.clientWidth
        };
    }
})(jQuery);

示例:

element.hasScrollBar()             // Returns { vertical: true/false, horizontal: true/false }
element.hasScrollBar().vertical    // Returns true/false
element.hasScrollBar().horizontal  // Returns true/false

答案 5 :(得分:12)

您需要element.scrollHeight。将其与$(element).height()进行比较。

答案 6 :(得分:7)

我创建了一个新的自定义:jQuery的伪选择器来测试一个项是否具有以下css属性之一:

  1. 溢出:[滚动|自动]
  2. overflow-x:[scroll | auto]
  3. overflow-y:[scroll | auto]
  4. 我想找到另一个元素中最接近的可滚动父级,所以我还写了另一个小jQuery插件来找到最接近溢出的父级。

    此解决方案可能效果不佳,但似乎确实有效。我将它与$ .scrollTo插件结合使用。有时我需要知道元素是否在另一个可滚动容器中。在这种情况下,我想滚动父可滚动元素与窗口。

    我可能应该将它包装在一个插件中,并将psuedo选择器作为插件的一部分添加,以及公开“最近”的方法来查找最近的(父)可滚动容器。

    Anywho ....在这里。

    $。isScrollable jQuery插件:

    $.fn.isScrollable = function(){
        var elem = $(this);
        return (
        elem.css('overflow') == 'scroll'
            || elem.css('overflow') == 'auto'
            || elem.css('overflow-x') == 'scroll'
            || elem.css('overflow-x') == 'auto'
            || elem.css('overflow-y') == 'scroll'
            || elem.css('overflow-y') == 'auto'
        );
    };
    

    $(':scrollable')jQuery伪选择器:

    $.expr[":"].scrollable = function(a) {
        var elem = $(a);
        return elem.isScrollable();
    };
    

    $ .rolllableparent()jQuery插件:

    $.fn.scrollableparent = function(){
        return $(this).closest(':scrollable') || $(window); //default to $('html') instead?
    };
    

    实施非常简单

    //does a specific element have overflow scroll?
    var somedivIsScrollable = $(this).isScrollable();
    //use :scrollable psuedo selector to find a collection of child scrollable elements
    var scrollableChildren = $(this).find(':scrollable');
    //use $.scrollableparent to find closest scrollable container
    var scrollableparent = $(this).scrollableparent();
    

    UPDATE:我发现Robert Koritnik已经提出了一个更强大的:可滚动的伪选择器,它将识别可滚动容器的可滚动轴和高度,作为他的$ .scrollintoview的一部分( )jQuery插件。 scrollintoview plugin

    这是他花哨的伪选择器(道具):

        $.extend($.expr[":"], {
    
        scrollable: function (element, index, meta, stack) {
    
            var direction = converter[typeof (meta[3]) === "string" && meta[3].toLowerCase()] || converter.both;
    
            var styles = (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(element, null) : element.currentStyle);
    
            var overflow = {
    
                x: scrollValue[styles.overflowX.toLowerCase()] || false,
    
                y: scrollValue[styles.overflowY.toLowerCase()] || false,
    
                isRoot: rootrx.test(element.nodeName)
    
            };
    
    
    
            // check if completely unscrollable (exclude HTML element because it's special)
    
            if (!overflow.x && !overflow.y && !overflow.isRoot)
    
            {
    
                return false;
    
            }
    
    
    
            var size = {
    
                height: {
    
                    scroll: element.scrollHeight,
    
                    client: element.clientHeight
    
                },
    
                width: {
    
                    scroll: element.scrollWidth,
    
                    client: element.clientWidth
    
                },
    
                // check overflow.x/y because iPad (and possibly other tablets) don't dislay scrollbars
    
                scrollableX: function () {
    
                    return (overflow.x || overflow.isRoot) && this.width.scroll > this.width.client;
    
                },
    
                scrollableY: function () {
    
                    return (overflow.y || overflow.isRoot) && this.height.scroll > this.height.client;
    
                }
    
            };
    
            return direction.y && size.scrollableY() || direction.x && size.scrollableX();
    
        }
    
    });
    

答案 7 :(得分:6)

上面的第一个解决方案仅适用于IE 上面的第二个解决方案仅适用于FF

这两种功能的组合适用于两种浏览器:

//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");
}​
  • 准备好文件
  • monitorWidth1:溢出设置为auto的div
  • mtc:monitorWidth1
  • 中的容器div
  • AdjustOverflowWidth:当滚动条处于活动状态时应用于#mtc div的css类 *使用警报测试跨浏览器,然后注释掉最终的生产代码。

HTH

答案 8 :(得分:5)

(scrollWidth / Height - clientWidth / Height)是滚动条存在的一个很好的指标,但它会给你一个&#34;误报&#34;多次回答。 如果你需要准确我会建议使用以下功能。 而不是试图猜测元素是否可滚动 - 你可以滚动它......

&#13;
&#13;
function isScrollable( el ){
  var y1 = el.scrollTop;
  el.scrollTop  += 1;
  var y2 = el.scrollTop;
  el.scrollTop  -= 1;
  var y3 = el.scrollTop;
  el.scrollTop   = y1;
  var x1 = el.scrollLeft;
  el.scrollLeft += 1;
  var x2 = el.scrollLeft;
  el.scrollLeft -= 1;
  var x3 = el.scrollLeft;
  el.scrollLeft  = x1;
  return {
    horizontallyScrollable: x1 !== x2 || x2 !== x3,
    verticallyScrollable: y1 !== y2 || y2 !== y3
  }
}
function check( id ){
  alert( JSON.stringify( isScrollable( document.getElementById( id ))));
}
&#13;
#outer1, #outer2, #outer3 {
  background-color: pink;
  overflow: auto;
  float: left;
}
#inner {
  width:  150px;
  height: 150px;
}
button {  margin: 2em 0 0 1em; }
&#13;
<div id="outer1" style="width: 100px; height: 100px;">
  <div id="inner">
    <button onclick="check('outer1')">check if<br>scrollable</button>
  </div>
</div>
<div id="outer2" style="width: 200px; height: 100px;">
  <div id="inner">
    <button onclick="check('outer2')">check if<br>scrollable</button>
  </div>
</div>
<div id="outer3" style="width: 100px; height: 180px;">
  <div id="inner">
    <button onclick="check('outer3')">check if<br>scrollable</button>
  </div>
</div>
&#13;
&#13;
&#13;

答案 9 :(得分:3)

呃大家在这里的答案都不完整,让我们停止在SO答案中使用jquery了。如果你想获得有关jquery的信息,请查看jquery的文档。

这是一个通用的纯javascript函数,用于测试元素是否具有完整的滚动条:

// dimension - Either 'y' or 'x'
// computedStyles - (Optional) Pass in the domNodes computed styles if you already have it (since I hear its somewhat expensive)
function hasScrollBars(domNode, dimension, computedStyles) {
    dimension = dimension.toUpperCase()
    if(dimension === 'Y') {
        var length = 'Height'
    } else {
        var length = 'Width'
    }

    var scrollLength = 'scroll'+length
    var clientLength = 'client'+length
    var overflowDimension = 'overflow'+dimension

    var hasVScroll = domNode[scrollLength] > domNode[clientLength]


    // Check the overflow and overflowY properties for "auto" and "visible" values
    var cStyle = computedStyles || getComputedStyle(domNode)
    return hasVScroll && (cStyle[overflowDimension] == "visible"
                         || cStyle[overflowDimension] == "auto"
                         )
          || cStyle[overflowDimension] == "scroll"
}

答案 10 :(得分:2)

上面提供的解决方案在大多数情况下都有效,但检查scrollHeight和overflow有时是不够的,而body和html元素则失败: https://codepen.io/anon/pen/EvzXZw

此解决方案检查元素是否可滚动:

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

注意:带有overflow = hidden的元素也会被视为可滚动(more info),因此如果需要,您也可以添加条件:

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

说明:诀窍是,向下滚动并还原它的尝试不会被浏览器呈现。最上面的函数也可以写成如下:

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;
}

答案 11 :(得分:1)

对于那些像我一样使用现代 js框架而不是JQuery并已被该线程的人们完全抛弃的可怜的灵魂,我将进一步扩展:

这是用Angular 6编写的,但是如果您编写React 16,Vue 2,Polymer,Ionic,React-Native,您将知道该怎么做以适应它。这是整个组件,因此应该很容易。

import {ElementRef, AfterViewInit} from '@angular/core';

@Component({
  selector: 'app',
  templateUrl: './app.html',
  styleUrls: ['./app.scss']
})
export class App implements AfterViewInit {
scrollAmount;

constructor(
  private fb: FormBuilder,
) {}

ngAfterViewInit(){
  this.scrollAmount = this.element.nativeElement.querySelector('.elem-list');
  this.scrollAmount.addEventListener('wheel', e => { //you can put () instead of e
  // but e is usefull if you require the deltaY amount.
    if(this.scrollAmount.scrollHeight > this.scrollAmount.offsetHeight){
       // there is a scroll bar, do something!
    }else{
       // there is NO scroll bar, do something!
    }
  });
}
}

在html中将存在一个带有“ elem-list”类的div,该div在css或scss中被样式化,以具有一个height和一个overflow以外的值。 }。 (因此hiddenauto

我在滚动事件时触发此评估,因为我的最终目标是拥有“自动焦点滚动”,如果这些组件没有垂直滚动可用,它们将决定是否将整个组件水平滚动,否则仅滚动内部组件。垂直的组件之一。

但是您可以将eval放在其他位置,以使它被其他东西触发。

这里要记住的重要一点是,您永远不会强制重新使用JQuery,总有一种方法可以不使用它而访问它具有的相同功能。

答案 12 :(得分:0)

这是Evan的答案的改进版本,似乎正确地解释了溢出逻辑。

            function element_scrollbars(node) {
                var element = $(node);
                var overflow_x = element.css("overflow-x");
                var overflow_y = element.css("overflow-y");
                var overflow = element.css("overflow");
                if (overflow_x == "undefined") overflow_x == "";
                if (overflow_y == "undefined") overflow_y == "";
                if (overflow == "undefined") overflow == "";
                if (overflow_x == "") overflow_x = overflow;
                if (overflow_y == "") overflow_y = overflow;
                var scrollbar_vertical = (
                    (overflow_y == "scroll")
                    || (
                        (
                            (overflow_y == "hidden")
                            || (overflow_y == "visible")
                        )
                        && (
                            (node.scrollHeight > node.clientHeight)
                        )
                    )
                );
                var scrollbar_horizontal = (
                    (overflow_x == "scroll")
                    || (
                        (
                            (overflow_x == "hidden")
                            || (overflow_x == "visible")
                        )
                        && (
                            (node.scrollWidth > node.clientWidth)
                        )
                    )
                );
                return {
                    vertical: scrollbar_vertical,
                    horizontal: scrollbar_horizontal
                };
            }

答案 13 :(得分:0)

这是我的改进:添加了parseInt。出于某些奇怪的原因,没有它就没有用。

// usage: jQuery('#my_div1').hasVerticalScrollBar();
// Credit: http://stackoverflow.com/questions/4814398/how-can-i-check-if-a-scrollbar-is-visible
(function($) {
    $.fn.hasVerticalScrollBar = function() {
        return this.get(0) ? parseInt( this.get(0).scrollHeight ) > parseInt( this.innerHeight() ) : false;
    };
})(jQuery);

答案 14 :(得分:0)

适用于 Chrome Edge Firefox Opera ,至少在较新版本中有效。

使用JQuery ......

设置此功能以修复页脚:

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());
        }
    }
}

它返回一个函数。这样做只是为了设置一次主体和页脚。

然后,在文档准备就绪时设置它。

$(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);
});

将此添加到您的页脚css:

footer {
    bottom: 0;
}

答案 15 :(得分:0)

提出的大部分答案让我接近我需要的地方,但不是那里。

我们基本上想要评估滚动条是否在正常情况下可见,通过该定义意味着body元素的大小大于视口。这不是一个提出的解决方案,这就是我提交它的原因。

希望它有所帮助!

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

基本上,我们有hasScrollbar函数,但如果请求的元素大于视图端口,则返回。对于视图端口大小,我们只使用了$(window).height()。快速比较元素大小,得出正确的结果和理想的行为。

答案 16 :(得分:0)

查找具有垂直滚动或正文的当前元素的父级。

$.fn.scrollableParent = function() {
    var $parents = this.parents();

    var $scrollable = $parents.filter(function(idx) {
        return this.scrollHeight > this.offsetHeight && this.offsetWidth !== this.clientWidth;
    }).first();

    if ($scrollable.length === 0) {
        $scrollable = $('html, body');
    }
    return $scrollable;
};

它可用于通过以下方式自动滚动到当前元素:

var $scrollable = $elem.scrollableParent();
$scrollable.scrollTop($elem.position().top);

答案 17 :(得分:0)

无框架JavaScript方法,同时检查垂直和水平

 /*
 * hasScrollBars
 * 
 * Checks to see if an element has scrollbars
 * 
 * @returns {object}
 */
Element.prototype.hasScrollBars = function() {
    return {"vertical": this.scrollHeight > this.style.height, "horizontal": this.scrollWidth > this.style.width};
}

像这样使用它

if(document.getElementsByTagName("body")[0].hasScrollBars().vertical){
            alert("vertical");
}

        if(document.getElementsByTagName("body")[0].hasScrollBars().horizontal){
            alert("horizontal");
}

答案 18 :(得分:0)

要考虑两个区域大小,即窗口和html。例如,如果html宽度大于窗口宽度,则滚动条可能会出现在用户界面上。因此,只需阅读窗口比例和html比例并进行基本数学运算即可。

要显示覆盖页面上方的箭头,可以通过简单的类列表切换操作完成,例如.hidden{display:none}

这是获取这些比例的跨浏览器方法。 (credit W3 Schools

|| document.body.clientWidth;

var h = window.innerHeight || document.documentElement.clientHeight ||
document.body.clientHeight; ```