ChatGPT解决这个技术问题 Extra ChatGPT

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

是否可以检查 div 的 overflow:auto

例如:

HTML

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

查询

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

});

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


C
Community

一个小插件。

(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 标记选择器上无法正常工作

演示

编辑

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

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

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

如果您有填充,则需要使用 > this.innerHeight(); jsfiddle.net/p3FFL/210
这样做有一个问题,如果水平滚动条也存在,那么即使垂直滚动条存在直到高度被水平滚动条高度缩小,这也会返回 false。
请注意,在 Mac 上,滚动条浮动在内容上方,不使用时会消失。在 Windows 上,它始终可见并占用水平空间。因此,仅仅因为内容可以滚动(这个函数检测到)并不意味着滚动条一定存在。
(function($) { $.fn.hasScrollBar = function() { return this.get(0).scrollWidth > this.width); } })(jQuery);这适用于水平溢出。适合在 iframe 中检查网站的移动响应能力。
scrollHeight > clientHeight,这适用于所有情况,包括填充、边框
N
Nick Bull

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

根据 MDN:

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

和:

Element.clientHeight 只读属性返回元素的内部高度(以像素为单位),包括填充,但不包括水平滚动条高度、边框或边距。 clientHeight 可以计算为 CSS 高度 + CSS 填充 - 水平滚动条的高度(如果存在)。

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

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

例如:github.com/twbs/bootstrap/blob/master/js/modal.js#L242 和 +1 用于 MDN 引用和解释!
在 chrome 中,如果内容的边框比它不包含在 scrollHeight 中
因不使用框架/库而被投票赞成。
小心 - 这会导致回流,这是性能消耗。 gist.github.com/paulirish/5d52fb081b3570c81e3a
每次直接调整元素大小时,您都必须运行此函数,或者它的一个子元素是(这也可能影响它)。如果没有提到这些,这个答案还不到一半。
S
Sean Zheng

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

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

在使用 JQuery .ready() 检查 DOM 是否准备好后,这个答案对我有用
这假设滚动条在窗口上,而不是 div 元素。建议将引用更改为建议:“如果您只需要测试主窗口上的滚动条,您可以尝试:”
S
SpyderScript

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

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

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


返回 (this.get(0))?this.get(0).scrollHeight>this.innerHeight():false;
我认为这应该被分配为正确的答案。这适用于 FF35、IE11 和 Chrome39。
它不会检查“溢出”值以确保在满足该 scrollHeight 条件时会出现滚动条。
@BT但是如果我在我的css中将溢出设置为自动,那么我不需要这个额外的检查吗?它比较大小,这就足够了......?
只对你有用的答案不是答案..你怎么知道其他人在他们的 css 中有什么?你的回答没有提到这个限制。如果有人无法提供您的答案并让它发挥作用,那么这不是一个好的答案。
E
Evan Trimboli

这扩展了@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

不适用于检查 上的垂直条,因为 scrollHeight 将始终等于 clientHeight,当元素使用 overflow:hidden 时也会返回无效结果
F
Francisco Costa

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


t
thegrandoverseer

我为 jQuery 制作了一个新的自定义 :pseudo 选择器来测试一个项目是否具有以下 css 属性之一:

溢出:[滚动|自动] 溢出-x:[滚动|自动] 溢出-y:[滚动|自动]

我想找到另一个元素最近的可滚动父元素,所以我还编写了另一个小 jQuery 插件来找到最近的溢出父元素。

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

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

任何人......在这里。

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

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

更新: 我发现 Robert Koritnik 已经想出了一个更强大的 :scrollable 伪选择器,它可以识别可滚动容器的可滚动轴和高度,作为他的 $.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();

    }

});

b
biziclop

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

函数 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;返回 { 水平滚动:x1 !== x2 || x2 !== x3,可垂直滚动:y1 !== y2 || y2 !== y3 } } 函数检查(id){ alert( JSON.stringify( isScrollable( document.getElementById( id )))); } #outer1,#outer2,#outer3 { 背景颜色:粉红色;溢出:自动;向左飘浮; } #inner { 宽度:150px;高度:150px; } 按钮 { 边距:2em 0 0 1em; }


在什么情况下会出现误报?
执行这些操作时有没有办法防止滚动事件?
B
B T

呃,这里的每个人的答案都不完整,请停止在 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"
}

为什么要避免在标记为 jquery 的问题上使用 jquery?请添加指向您提到的 jquery 文档部分的链接。
@kpull1 太多人在他们遇到的每一个 javascript 问题上都标记 jQuery。这个问题与 jQuery 有 0 关系。 jQuery 文档中没有任何部分有答案,因为 jQuery 不这样做,也不应该这样做。
C
Chamika Sandamal

上面的第一个解决方案仅适用于 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:溢出设置为自动的div

mtc:monitorWidth1 内的容器 div

AdjustOverflowWidth :当滚动条处于活动状态时应用于#mtc div 的css 类 *使用警报测试跨浏览器,然后注释掉最终生产代码。

高温高压


t
tatsu

对于那些像我一样使用现代 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,
  private element: ElementRef 
) {}

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,它在 css 或 scss 中被风格化为有一个 height 和一个不是 hiddenoverflow 值。 (所以 autosroll

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

但是您可以将 eval 放在其他地方,让它被其他东西触发。

这里要记住的重要一点是,您永远不会被迫重新使用 JQuery,总有一种方法可以在不使用它的情况下访问它所具有的相同功能。


好奇你为什么要监听滚轮事件来检查是否有滚动条。
此外,由于您使用的是箭头函数,this 保留父范围; th = this; 是不必要的。
@mix3d 我个人使用此代码在水平和垂直滚动之间自动切换,基于哪个在给定的指向元素上具有滚动方向是动态的
回复:这个;它基本上是 function(){}.bind(this) 的语法糖(加上漂亮的速记)
R
Robbendebiene

上面提供的解决方案在大多数情况下都可以使用,但检查 scrollHeight 和溢出有时是不够的,并且可能会因为 body 和 html 元素而失败,如下所示:https://codepen.io/anon/pen/EvzXZw

1. 解决方案 - 检查元素是否可滚动:

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

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

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

据我所知,此方法仅在元素具有 scroll-behavior: smooth 时才会失败。

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

function isScrollableY (element) { // 如果 scrollTop 不为 0 / 大于 0,则元素会滚动,因此必须是可滚动的 // -> true if (element.scrollTop === 0) { // 如果元素是零它可能是可滚动的 // -> 尝试滚动大约 1 个像素 element.scrollTop++; // 如果元素为零,则滚动不成功,因此不可滚动 // -> false if (element.scrollTop === 0) return false; // 否则元素是可滚动的;重置 scrollTop 属性 // -> true element.scrollTop--; } 返回真; }

2. 解决方案 - 进行所有必要的检查:

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

J
JBlitzen

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

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

B
Barry Chapman

提供的大多数答案让我接近了我需要的地方,但并不完全在那里。

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

希望它可以帮助某人!

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

本质上,我们有 hasScrollbar 函数,但如果请求的元素大于视口,则返回。对于视口大小,我们只使用了 $(window).height()。将其与元素大小进行快速比较,会产生正确的结果和理想的行为。


S
Svetoslav Marinov

这是我的改进:添加了 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);

M
Mateus Pires

适用于 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;
}

D
Dmitriy Sintsov

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

$.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);

D
David Clews

无框架 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");
}

R
Ronnie Royston

有两个区域大小需要考虑,窗口和 html。例如,如果 html 宽度大于窗口宽度,则用户界面上可能会出现滚动条。所以这是阅读窗口比例和 html 比例并进行基本数学运算的问题。

至于在页面顶部显示一个箭头,这是通过一个简单的类列表切换来完成的,例如 .hidden{display:none}

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

||文档.body.clientWidth; var h = window.innerHeight ||文档.documentElement.clientHeight ||文档.body.clientHeight; ```