Verifique con jquery si div tiene elementos desbordados

130

Tengo un div con una altura fija y overflow:hidden;

Quiero verificar con jQuery si el div tiene elementos que se desbordan más allá de la altura fija del div. ¿Cómo puedo hacer esto?

Justin Meltzer
fuente
Podría estar equivocado, pero no creo que haya una forma mágica de jQuery para verificar si un elemento está fuera de otro elemento. Probablemente tenga que verificar la altura y la posición de los elementos dentro de su div y hacer algunos cálculos para ver si se desbordan.
Adeneo
1
Sí, estaba pensando en verificar si la diferencia entre la posición de la parte superior del div y la posición de la parte inferior del último elemento hijo dentro del div era mayor que la altura del div
Justin Meltzer
Posible duplicado del desbordamiento de elementos
Noyo

Respuestas:

281

En realidad, no necesita ningún jQuery para verificar si hay un desbordamiento o no. El uso de element.offsetHeight, element.offsetWidth, element.scrollHeighty element.scrollWidthse puede determinar si el elemento tiene contenido más grande que su tamaño:

if (element.offsetHeight < element.scrollHeight ||
    element.offsetWidth < element.scrollWidth) {
    // your element have overflow
} else {
    // your element doesn't have overflow
}

Ver ejemplo en acción: Fiddle

Pero si desea saber qué elemento dentro de su elemento es visible o no, entonces necesita hacer más cálculos. Hay tres estados para un elemento hijo en términos de visibilidad:

ingrese la descripción de la imagen aquí

Si desea contar elementos semi-visibles, sería el script que necesita:

var invisibleItems = [];
for(var i=0; i<element.childElementCount; i++){
  if (element.children[i].offsetTop + element.children[i].offsetHeight >
      element.offsetTop + element.offsetHeight ||
      element.children[i].offsetLeft + element.children[i].offsetWidth >
      element.offsetLeft + element.offsetWidth ){

        invisibleItems.push(element.children[i]);
    }

}

Y si no desea contar semi-visible, puede calcular con una pequeña diferencia.

Mohsen
fuente
Corrígeme si me equivoco pero parece que ya no funciona Chrome V.20.0.1132.57. Si cambia el texto dentro del div, el color de fondo permanece amarillo, jsbin.com/ujiwah/25/edit#javascript,html,live
Robbie
44
@Robbie <p>es un elemento de nivel de bloque y ocupa un 100% de ancho. Si desea probar esto con la cantidad de texto dentro de la p simplemente haga p{display:inline}. De esta manera, el texto interior determina el ancho de p.
Mohsen
Leí "En realidad no necesitas ningún jQuery" e inmediatamente dije "duh, es matemática simple".
Michael J. Calkins
1
Funciona para la mayoría de los casos, pero no cubrirá el escenario con tablas CSS (display table-cell, table-rwo, table) -
Dmitry
Entiendo que offsetHeight incluye bordes, que no cuentan para el área desplazable. Solo una nota. (corrígeme si me equivoco)
Lodewijk
38

Tenía la misma pregunta que el OP, y ninguna de esas respuestas se ajustaba a mis necesidades. Necesitaba una condición simple, para una necesidad simple.

Aquí está mi respuesta:

if ($("#myoverflowingelement").prop('scrollWidth') > $("#myoverflowingelement").width() ) {
  alert("this element is overflowing !!");
}
else {
 alert("this element is not overflowing!!");
}

Además, puede cambiar scrollWidthpor scrollHeightsi necesita probar cualquiera de los casos.

sidney
fuente
1
Gracias, eso funcionó para mí. solo necesitaba un ejemplo simple en jquery pero no en js simple.
mikhail-t
44
no funciona para elementos con relleno / margen. utilizar el ancho de vía externo (verdadero) de ancho
Vladimir Shmidt
No funciona en ie, funciona bien en mozilla y cromo.
Sushil Kumar
Tengo algunos efectos extraños con este script. Pruebas en Chrome. Lo reescribí para verificar la altura (usando OuterHeight) y si uso F5 para volver a cargar una página para verificar el script, o navego desde otra página, siempre vuelve como overflow = true, pero si uso ctrl-F5 viene de vuelta como desbordamiento = falso. Esto es cuando se prueba una situación que se supone que es falsa. Cuando se supone que es verdad, siempre funciona.
Dennis
Ok, lo descubrí yo mismo. Tengo mis etiquetas de script envueltas en window.addEventListener ('DOMContentLoaded') para que funcionen con mi jquery cargado de forma asincrónica y otros archivos. Pero ejecutar este script en esa etapa devuelve lecturas aparentemente falsas, por lo que para este script reemplacé DOMContentLoaded con solo 'cargar' para retrasar aún más la ejecución del script. Ahora devuelve resultados correctos cada vez. Y para mis propósitos, está perfectamente bien que espere ejecutarlo hasta que se cargue la página, incluso puedo agregar una animación para resaltar la atención de los usuarios a un botón "leer más".
Dennis
4

Entonces utilicé la biblioteca jquery desbordante: https://github.com/kevinmarx/overflowing

Después de instalar la biblioteca, si desea asignar la clase overflowinga todos los elementos desbordados, simplemente ejecute:

$('.targetElement').overflowing('.parentElement')

Esto le dará a la clase overflowing, como <div class="targetElement overflowing">a todos los elementos que se desbordan. Luego, puede agregar esto a algún controlador de eventos (clic, mouseover) u otra función que ejecute el código anterior para que se actualice dinámicamente.

maudulus
fuente
3

Parcialmente basado en la respuesta de Mohsen (la primera condición adicional cubre el caso donde el niño está oculto antes que el padre):

jQuery.fn.isChildOverflowing = function (child) {
  var p = jQuery(this).get(0);
  var el = jQuery(child).get(0);
  return (el.offsetTop < p.offsetTop || el.offsetLeft < p.offsetLeft) ||
    (el.offsetTop + el.offsetHeight > p.offsetTop + p.offsetHeight || el.offsetLeft + el.offsetWidth > p.offsetLeft + p.offsetWidth);
};

Entonces solo haz:

jQuery('#parent').isChildOverflowing('#child');
brauliobo
fuente
2

Un método es verificar scrollTop contra sí mismo. Dele al contenido un valor de desplazamiento mayor que su tamaño y luego verifique si su scrollTop es 0 o no (si no es 0, se ha desbordado).

http://jsfiddle.net/ukvBf/

Joseph Marikle
fuente
1

En inglés simple: Obtenga el elemento padre. Verifique su altura y guarde ese valor. Luego recorra todos los elementos secundarios y verifique sus alturas individuales.

Esto está sucio, pero puede tener la idea básica: http://jsfiddle.net/VgDgz/

Doozer Blake
fuente
1
Es un buen ejemplo, pero ¿qué pasa con el puesto? Si un elemento se posiciona absoluto en la parte superior del elemento primario, podría desbordarse incluso si la altura es más baja que el elemento primario.
adeneo
Absolutamente, es probable que haya bastantes casos diferentes que podrían causarlo. Solo un ejemplo rápido de por dónde empezar. El caso específico de Op probablemente definirá lo que debe verificarse
Doozer Blake
0

Aquí hay una solución jQuery pura, pero es bastante desordenada:

var div_height = $(this).height();
var vertical_div_top_position = $(this).offset().top;
var lastchild_height = $(this).children('p:last-child').height();
var vertical_lastchild_top_position = $(this).children('p:last-child').offset().top;
var vertical_lastchild_bottom_position = lastchild_height + vertical_lastchild_top_position;
var real_height = vertical_lastchild_bottom_position - vertical_div_top_position;

if (real_height > div_height){
    //overflow div
}
Justin Meltzer
fuente
0

Esta es la solución jQuery que funcionó para mí. offsetWidthetc. no funcionó.

function is_overflowing(element, extra_width) {
    return element.position().left + element.width() + extra_width > element.parent().width();
}

Si esto no funciona, asegúrese de que el elemento primario de los elementos tenga el ancho deseado (personalmente, tuve que usarlo parent().parent()). positionEs relativo al elemento primario. También lo he incluido extra_widthporque mis elementos ("etiquetas") contienen imágenes que requieren poco tiempo para carga, pero durante la llamada a la función tienen ancho cero, lo que estropea el cálculo. Para evitarlo, utilizo el siguiente código de llamada:

var extra_width = 0;
$(".tag:visible").each(function() {
    if (!$(this).find("img:visible").width()) {
        // tag image might not be visible at this point,
        // so we add its future width to the overflow calculation
        // the goal is to hide tags that do not fit one line
        extra_width += 28;
    }
    if (is_overflowing($(this), extra_width)) {
        $(this).hide();
    }
});

Espero que esto ayude.

Dennis Golomazov
fuente
0

Lo arreglé agregando otro div en el que se desborda. Luego comparas las alturas de los 2 divs.

<div class="AAAA overflow-hidden" style="height: 20px;" >
    <div class="BBBB" >
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </div>
</div>

y el js

    if ($('.AAAA').height() < $('.BBBB').height()) {
        console.log('we have overflow')
    } else {
        console.log('NO overflow')
    }

Esto parece más fácil ...

alex toader
fuente