Как проверить, видима ли полоса прокрутки?
Можно ли проверить overflow:auto
div?
Например:
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'):
}
}
});
Иногда это короткое содержание (без полосы прокрутки), а иногда и длинное (видимость полосы прокрутки).
Ответы
Ответ 1
маленький плагин для него.
(function($) {
$.fn.hasScrollBar = function() {
return this.get(0).scrollHeight > this.height();
}
})(jQuery);
используйте его так:
$('#my_div1').hasScrollBar(); // returns true if there a `vertical` scrollbar, false otherwise..
протестирован, работая над Firefox, Chrome, IE6,7,8
но не работает должным образом в селекторе body
Изменить
Я узнал, что когда у вас есть горизонтальная полоса прокрутки, которая вызывает вертикальную полосу прокрутки, эта функция не работает....
Я обнаружил другое решение... используйте clientHeight
return this.get(0).scrollHeight > this.get(0).clientHeight;
Ответ 2
Возможно, более простое решение.
if ($(document).height() > $(window).height()) {
// scrollbar
}
Ответ 3
Я должен немного изменить то, что сказал Рейгель:
(function($) {
$.fn.hasScrollBar = function() {
return this[0] ? this[0].scrollHeight > this.innerHeight() : false;
}
})(jQuery);
innerHeight считает высоту элемента управления и его верхние и нижние отступы
Ответ 4
Вы можете сделать это, используя комбинацию Element.scrollHeight
и Element.clientHeight
.
Согласно MDN:
Атрибут Element.scrollHeight только для чтения - это измерение высоты содержимого элемента, включая контент, невидимый на экране из-за переполнения. Значение scrollHeight равно минимальному клиентуHeight, который потребуется элементу для того, чтобы соответствовать всему содержимому в точке обзора, не используя вертикальную полосу прокрутки. Он включает в себя дополнение элемента, но не его край.
и
Свойство Element.clientHeight только для чтения возвращает внутреннюю высоту элемента в пикселях, включая заполнение, но не горизонтальную высоту полосы прокрутки, границу или маржу.
clientHeight может быть рассчитан как высота CSS + добавление CSS - высота горизонтальной полосы прокрутки (если присутствует).
Следовательно, элемент отобразит полосу прокрутки, если высота прокрутки больше высоты клиента, поэтому ответ на ваш вопрос:
function scrollbarVisible(element) {
return element.scrollHeight > element.clientHeight;
}
Ответ 5
Это расширяется при ответе @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
Ответ 6
Вам нужен element.scrollHeight. Сравните это с $(element).height()
.
Ответ 7
Я создал новый пользовательский псевдо-селектор для jQuery, чтобы проверить, имеет ли элемент один из следующих свойств css:
- переполнение: [прокрутка | авто]
- переполнение-x: [прокрутка | авто]
- 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();
};
$. 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();
ОБНОВЛЕНИЕ:. Я обнаружил, что Роберт Коритник уже придумал гораздо более мощный: прокручиваемый псевдоселектор, который будет идентифицировать прокручиваемые оси и высоту прокручиваемых контейнеров, как часть его $.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 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();
}
});
Ответ 8
Первое решение выше работает только в 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, где для переполнения установлено значение auto
- mtc: контейнер div внутри monitorWidth1
- AdjustOverflowWidth: класс css применяется к div #mtc, когда активна полоса прокрутки
* Используйте оповещение для проверки кросс-браузера, а затем закомментируйте окончательный производственный код.
НТН
Ответ 9
(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>
Ответ 10
Ух, ответы на все здесь неполны, и, пожалуйста, прекратите использовать jquery в SO-ответах. Проверьте документацию jquery, если вы хотите получить информацию о jquery.
Здесь обобщенная функция pure-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"
}
Ответ 11
Я собираюсь рассказать об этом еще дальше тем беднягам, которые, как и я, используют одну из современных 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 будет div с классом "elem-list", который стилизован в css или scss, чтобы иметь значение height
и overflow
, которое не является hidden
. (так auto
или sroll
)
Я запускаю это значение при событии прокрутки, потому что моей конечной целью было иметь "автоматическую прокрутку фокуса", которая решает, прокручивают ли они весь набор компонентов по горизонтали, если у указанных компонентов нет доступной вертикальной прокрутки, а в противном случае прокручивает только внутренности одного из компоненты по вертикали.
но вы можете поместить eval в другом месте, чтобы он мог быть вызван чем-то другим.
Здесь важно помнить, что вы никогда не будете вынуждены снова использовать JQuery, всегда есть способ получить доступ к тем же функциональным возможностям, которые у него есть, без его использования.
Ответ 12
Здесь улучшенная версия ответа 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
Решения, приведенные выше, будут работать в большинстве случаев, но проверка scrollHeight и переполнения иногда недостаточна и не выполняется для элементов body и html:
https://codepen.io/anon/pen/EvzXZw
Это решение проверяет, прокручивается ли элемент:
function isScrollableY (element) {
return !!(element.scrollTop || (++element.scrollTop && element.scrollTop--));
}
Примечание: элементы с переполнением = скрытые также рассматриваются как прокручиваемые (дополнительная информация), поэтому вы можете при необходимости добавьте условие против этого:
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;
}
Ответ 14
Здесь мое улучшение: добавлено 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);
Ответ 15
Работает с 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;
}
Ответ 16
Большинство представленных ответов приблизили меня к тому месту, где я должен был быть, но не совсем там.
Мы в основном хотели оценить, будут ли полосы прокрутки видимыми в нормальной ситуации, по этому определению, означающему, что размер элемента body больше, чем порт представления. Это не было представлено решение, поэтому я представляю его.
Надеюсь, это кому-нибудь поможет!
(function($) {
$.fn.hasScrollBar = function() {
return this.get(0).scrollHeight > $(window).height();
}
})(jQuery);
По сути, у нас есть функция hasScrollbar
, но она возвращается, если запрошенный элемент больше, чем порт представления. Для просмотра размера порта мы просто использовали $(window).height()
. Быстрое сравнение этого с размером элемента, дает правильные результаты и желаемое поведение.
Ответ 17
Найдите родителя текущего элемента с вертикальной прокруткой или телом.
$.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);