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

是否有可能检查一个div的overflow:auto ?

例如:

超文本标记语言

<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'):
}
}


});

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

375806 次浏览

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

一个小插件。

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

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

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

我应该修改一下雷盖尔的话

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

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

上面的第一个解决方案只适用于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

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

  1. 溢出(滚动|汽车):
  2. overflow-x(滚动|汽车):
  3. overflow-y(滚动|汽车):

我想找到另一个元素的最近的可滚动父元素,所以我还写了另一个小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();
};

jQuery插件$.scrollableparent()

$.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已经提出了一个更强大的:可滚动的伪选择器,它将识别可滚动的轴和可滚动容器的高度,作为他的$.scrollintoview() jQuery插件的一部分。scrollintoview插件

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

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


}


});

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

你可以使用Element.scrollHeightElement.clientHeight属性的组合来做到这一点。

根据MDN:

Element.scrollHeight只读属性是对元素内容高度的测量,包括由于溢出而在屏幕上不可见的内容。scrollHeight值等于元素为了适应视点中的所有内容而不使用垂直滚动条所需的最小clientHeight。包含元素的padding,但不包含元素的margin。

和:

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

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

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

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

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

呃,这里每个人的答案都是不完整的,让我们停止使用jquery在SO答案已经请。如果你想了解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"
}

这里是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
};
}

(scrollWidth/Height - clientWidth/Height)是滚动条存在的一个很好的指示器,但在很多情况下它会给你一个“假阳性”的答案。 如果你需要精确,我建议使用下面的函数。

.

.

.

.

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 ))));
}
#outer1, #outer2, #outer3 {
background-color: pink;
overflow: auto;
float: left;
}
#inner {
width:  150px;
height: 150px;
}
button {  margin: 2em 0 0 1em; }
<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>

适用于边缘火狐歌剧,至少在新版本中。

使用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;
}
上面提供的解决方案将在大多数情况下工作,但检查scrollHeight和溢出有时是不够的,可以失败的body和html元素如下所示: https://codepen.io/anon/pen/EvzXZw < / p >

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

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

带有overflow: hidden注意:元素也被视为可滚动的(更多信息),所以如果需要,你也可以添加一个条件:

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) {
// 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. 解决方案——做所有必要的检查:

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

他们给出的大多数答案都让我接近了我想要达到的目标,但还没有达到。

我们基本上想要评估滚动条在正常情况下是否可见,根据定义,body元素的大小大于视图端口。这不是一个提出的解决办法,这就是我提出它的原因。

希望它能帮助到某些人!

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

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

找到具有垂直滚动或主体的当前元素的父元素。

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

我将为那些像我一样使用现代 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中会有一个带有类“element -list”的div,它在css或scss中被风格化,具有heightoverflow值,而不是hidden。(所以autosroll)

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

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

这里要记住的重要事情是,你永远不会再使用强迫来使用JQuery,总有一种方法可以在不使用它的情况下访问它具有的相同功能。

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

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

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

这里有一个跨浏览器的方法来获得这些比例。(W3学校)

|| document.body.clientWidth;


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

我有一个问题,我需要检查,如果滚动条是可见的整个屏幕(主体)或不。Chrome有能力隐藏滚动条,尽管有一个溢出发生的事实,因此主体是可滚动的。

因此,上面的解决方案对我不起作用。我现在检查,如果有滚动条如下方式:

const isScrollbarPresent = () => {
const beforeScrollbarHidden = document.body.clientWidth;
const overflowState = document.body?.style.overflow;
document.body.style.overflow = 'hidden';
const afterScrollbarHidden = document.body.clientWidth;
document.body.style.overflow = overflowState;
return beforeScrollbarHidden !== afterScrollbarHidden;
};

我得到主体的宽度,有或没有滚动条,并保存主体的当前溢出状态。然后隐藏滚动条。如果有滚动条,主体的宽度现在会更大。如果不是,宽度是相同的。之后,我恢复溢出状态。

另一个简单的答案是:

export const isScrollbarPresent = (element?: HTMLElement) => {
const testedElement = element ?? document.body;
return testedElement.scrollHeight > testedElement.clientHeight; }

我检查元素的scrollHeight是否大于clientHeight。scrollHeight返回一个元素的绝对高度,包括所有不可见的元素。clientHeight返回屏幕上可见的高度。