tipos tiene saber posicion obtener hace div detectar desplazamiento cuando cambiar javascript jquery scroll overflow

javascript - posicion - saber si un div tiene scroll



¿Cómo puedo comprobar si hay una barra de desplazamiento visible? (17)

(scrollWidth / Height - clientWidth / Height) es un buen indicador de la presencia de una barra de desplazamiento, pero le dará una respuesta "falsa positiva" en muchas ocasiones. Si necesita ser preciso, sugeriría usar la siguiente función. En lugar de intentar adivinar si el elemento es desplazable, puede desplazarlo ...

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>

¿Es posible controlar el overflow:auto de un div?

Por ejemplo:

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

A veces el contenido es corto (sin barra de desplazamiento) y, a veces, largo (barra de desplazamiento visible).


Aquí está mi mejora: agregado parseInt. Por alguna extraña razón no funcionó sin él.

// usage: jQuery(''#my_div1'').hasVerticalScrollBar(); // Credit: http://.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);


Aquí hay una versión mejorada de la respuesta de Evan que parece explicar adecuadamente la lógica de desbordamiento.

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


Debería cambiar un poco de lo que dijo Reigel:

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

innerHeight cuenta la altura del control y sus acolchados superior e inferior


Encuentra un elemento primario del elemento actual que tenga desplazamiento vertical o cuerpo.

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

Se puede utilizar para desplazarse automáticamente al elemento actual a través de:

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


Esto se expande en la respuesta de @Reigel. Devolverá una respuesta para barras de desplazamiento horizontal o vertical.

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

Ejemplo:

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


Funciona en Chrome , Edge , Firefox y Opera , al menos en las versiones más nuevas.

Usando JQuery ...

Configura esta función para arreglar el pie de página:

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

Devuelve una función. Hecho de esta manera sólo para establecer el cuerpo y el pie de página una vez.

Y luego, establezca esto cuando el documento esté listo.

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

Agrega esto a tu pie de página css:

footer { bottom: 0; }


Hice una nueva costumbre: pseudo selector para jQuery para probar si un elemento tiene una de las siguientes propiedades css:

  1. desbordamiento: [scroll | auto]
  2. overflow-x: [scroll | auto]
  3. overflow-y: [scroll | auto]

Quería encontrar el elemento primario más cercano con desplazamiento de otro elemento, así que también escribí otro pequeño complemento de jQuery para encontrar al padre más cercano con un desbordamiento.

Esta solución probablemente no funciona mejor, pero parece funcionar. Lo usé junto con el complemento $ .scrollTo. A veces necesito saber si un elemento está dentro de otro contenedor desplazable. En ese caso, quiero desplazar el elemento de desplazamiento padre frente a la ventana.

Probablemente debería haber envuelto esto en un solo complemento y haber agregado el selector psuedo como parte del complemento, así como exponer un método "más cercano" para encontrar el contenedor desplazable más cercano (principal).

Anywho .... aquí está.

$ .isSplollable jQuery plugin:

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

$ ('': desplazable'') pseudo selector jQuery:

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

$ .scrollableparent () complemento de jQuery:

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

La implementación es bastante simple

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

ACTUALIZACIÓN: encontré que Robert Koritnik ya había creado un pseudo selector desplazable mucho más poderoso que identificará los ejes desplazables y la altura de los contenedores desplazables, como parte de su complemento $ .scrollintoview () jQuery. plugin scrollintoview

Aquí está su elegante pseudo selector (accesorios):

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


La mayoría de las respuestas presentadas me acercaron a donde necesitaba estar, pero no del todo.

Básicamente, queríamos evaluar si las barras de desplazamiento, que serían visibles en una situación normal, por esa definición significa que el tamaño del elemento del cuerpo es mayor que el puerto de vista. Esta no fue una solución presentada, por lo que la envío.

Esperemos que ayude a alguien!

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

Esencialmente, tenemos la función hasScrollbar , pero hasScrollbar si el elemento solicitado es más grande que el puerto de vista. Para ver el tamaño del puerto, solo usamos $(window).height() . Una comparación rápida de eso con el tamaño del elemento, produce los resultados correctos y el comportamiento deseable.


La primera solución anterior solo funciona en IE La segunda solución anterior solo funciona en FF

Esta combinación de ambas funciones funciona en ambos navegadores:

//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"); }​

  • Envolver en un documento listo
  • monitorWidth1: el div donde el desbordamiento se establece en auto
  • mtc: un contenedor div dentro de monitorWidth1
  • AdjustOverflowWidth: una clase css aplicada a la división #mtc cuando la barra de desplazamiento está activa * Use la alerta para probar el navegador cruzado y luego comente el código de producción final.

HTH


Las respuestas de todos aquí son incompletas, y dejemos de usar jquery en las respuestas de SO, por favor. Consulte la documentación de jquery si desea información sobre jquery.

Aquí hay una función generalizada de javascript puro para probar si un elemento tiene barras de desplazamiento de una manera completa:

// 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" }


Las soluciones proporcionadas anteriormente funcionarán en la mayoría de los casos, pero verificar el scrollHeight y el desbordamiento a veces no es suficiente y fallan los elementos del cuerpo y html: https://codepen.io/anon/pen/EvzXZw

Esta solución comprueba si el elemento es desplazable:

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

Nota: los elementos con desbordamiento = oculto también se tratan como desplazables ( más información ), por lo que también puede agregar una condición si es necesario:

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

Explicación: el truco es que el intento de desplazarse hacia abajo y revertirlo no será procesado por el navegador. La función superior se puede escribir como la siguiente:

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



Puede hacer esto utilizando una combinación de los atributos Element.scrollHeight y Element.clientHeight .

Según MDN:

El atributo de solo lectura Element.scrollHeight es una medida de la altura del contenido de un elemento, incluido el contenido no visible en la pantalla debido a un desbordamiento. El valor de scrollHeight es igual al valor mínimo de clientHeight que requeriría el elemento para ajustar todo el contenido en el punto de vista sin utilizar una barra de desplazamiento vertical. Incluye el relleno del elemento pero no su margen.

Y:

La propiedad de solo lectura Element.clientHeight devuelve la altura interior de un elemento en píxeles, incluido el relleno pero no la altura, el borde o el margen de la barra de desplazamiento horizontal.

clientHeight se puede calcular como altura de CSS + relleno de CSS: altura de la barra de desplazamiento horizontal (si está presente).

Por lo tanto, el elemento mostrará una barra de desplazamiento si la altura de desplazamiento es mayor que la altura del cliente, por lo que la respuesta a su pregunta es:

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


Tal vez una solución más simple.

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


Un pequeño plugin para ello.

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

usalo asi

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

probado trabajando en Firefox, Chrome, IE6,7,8

pero no funciona correctamente en body selector de etiquetas del body

demo

Editar

Descubrí que cuando tiene una barra de desplazamiento horizontal que hace que aparezca una barra de desplazamiento vertical, esta función no funciona ...

Encontré otra solución ... use clientHeight

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


Voy a extenderme sobre esto aún más para aquellas almas pobres que, como yo, usan uno de los marcos js modernos y no JQuery y han sido totalmente abandonados por la gente de este hilo:

Esto se escribió en Angular 6, pero si escribe React 16, Vue 2, Polymer, Ionic, React-Native, sabrá qué hacer para adaptarlo. Y es todo el componente por lo que debería ser fácil.

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

en el html habría un div con la clase "elem-list" que está estilizada en css o scss para tener una height y un valor de overflow que no esté hidden . ( auto o sroll )

Activar esta evaluación en un evento de desplazamiento porque mi objetivo final era tener "desplazamientos de enfoque automático" que deciden si están desplazando todo el conjunto de componentes horizontalmente si dichos componentes no tienen disponible un desplazamiento vertical y, de lo contrario, solo desplazarán las entrañas de uno de los componentes verticalmente.

pero puede colocar la evaluación en otro lugar para que se active mediante otra cosa.

Lo importante a recordar aquí es que nunca volverás a usar JQuery, siempre hay una forma de acceder a las mismas funcionalidades que tiene sin usarla.