2012-02-17 8 views
59

¿Cuál es la forma más fácil de detectar si un elemento se ha desbordado?javascript css comprobar si se produjo un desbordamiento

Mi caso de uso es, quiero limitar un determinado cuadro de contenido para tener una altura de 300 px. Si el contenido interno es más alto que eso, lo corté con un desbordamiento. Pero si se desborda, quiero mostrar un botón 'más', pero si no, no quiero mostrar ese botón.

¿Hay alguna manera fácil de detectar el desbordamiento, o hay un método mejor? Gracias.

Respuesta

4

¿Algo como esto: http://jsfiddle.net/Skooljester/jWRRA/1/ funciona? Simplemente verifica la altura del contenido y lo compara con la altura del contenedor. Si es mayor de lo que puede poner en el código para agregar un botón "Mostrar más".

Actualización: Agregó el código para crear un botón "Mostrar más" en la parte superior del contenedor.

0

js Se utiliza para comprobar si el niño es offsetHeight más de los padres .. si lo es, hacer que los padres desbordan scroll/hidden/auto lo que usted quiere y también en la display:block más div ..

0

Puede comprobar los límites relativos para el padre desplazado.

// Position of left edge relative to frame left courtesy 
// http://www.quirksmode.org/js/findpos.html 
function absleft(el) { 
    var x = 0; 
    for (; el; el = el.offsetParent) { 
    x += el.offsetLeft; 
    } 
    return x; 
} 

// Position of top edge relative to top of frame. 
function abstop(el) { 
    var y = 0; 
    for (; el; el = el.offsetParent) { 
    y += el.offsetTop; 
    } 
    return y; 
} 

// True iff el's bounding rectangle includes a non-zero area 
// the container's bounding rectangle. 
function overflows(el, opt_container) { 
    var cont = opt_container || el.offsetParent; 
    var left = absleft(el), right = left + el.offsetWidth, 
     top = abstop(el), bottom = top + el.offsetHeight; 
    var cleft = absleft(cont), cright = cleft + cont.offsetWidth, 
     ctop = abstop(cont), cbottom = ctop + cont.offsetHeight; 
    return left < cleft || top < ctop 
     || right > cright || bottom > cbottom; 
} 

Si pasa esto un elemento que le dirá si sus límites son del todo dentro de un contenedor, y será por defecto de los padres de desplazamiento del elemento si no se proporciona ningún contenedor explícita. Utiliza

3

Si está utilizando jQuery, puede intentar un truco: hacer div exterior con overflow: hidden y div interno con contenido. Luego use la función .height() para verificar si la altura del div interno es mayor que la altura del div externo. No estoy seguro de que funcione, pero pruébalo.

3

Comparando element.scrollHeight a element.clientHeight debería hacer la tarea.

+0

Muchas gracias, parece no estándar sin embargo. – Harry

+0

Sí, pero de acuerdo con [quirksmode] (http://quirksmode.org/dom/w3c_cssom.html#elementview) funciona para la mayoría, y es mucho más simple que las otras soluciones publicadas. – Bergi

+0

@Harry: es compatible con todos los navegadores actuales (al menos los de escritorio), por lo que no importa que sea formalmente no estándar. –

1

Otro problema que debe tener en cuenta es la falta de disponibilidad de JS. Piensa en el encantamiento progresivo o la degradación elegante. Yo sugeriría:

  • añadir "más botón de" por defecto
  • añadir reglas de desbordamiento por defecto
  • botón de ocultar y si las modificaciones necesarias en CSS JS después de comparar element.scrollHeight a element.clientHeight
100

Esta función devolverá el valor booleano si se desborda el elemento DOM:

function isOverflown(element) { 
    return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth; 
} 

El elemento puede desbordarse vertical u horizontalmente o ambos

+29

¡Gran solución! Aquí hay una variante de jQuery (para usar con '$ (" # element "). Overflown()'): '$ .fn.overflown = function() {var e = this [0]; return e.scrollHeight> e. clientHeight || e.scrollWidth> e.clientWidth;} ' – Sygmoral

+0

@micnic hi, estoy usando ionic2 y trato de hacer lo mismo ... pero la función devuelve verdadera siempre ... ¿hay alguna manera diferente de hacer las cosas en angular 2 – Yasir

+0

@DavidBracoly, esta función es para DOM API pura, no tengo experiencia con Ionic/Angular, supongo que debería obtener el elemento DOM original y usar esta función – micnic

1

Aquí hay un violín para determinar si un elemento se ha desbordado usando un divisor envoltorio con desbordamiento: oculto y JQuery height() para medir la diferencia entre el envoltorio y un interno contenido div.

outers.each(function() { 
    var inner_h = $(this).find('.inner').height(); 
    console.log(inner_h); 
    var outer_h = $(this).height(); 
    console.log(outer_h); 
    var overflowed = (inner_h > outer_h) ? true : false; 
    console.log("overflowed = ", overflowed); 
}); 

Fuente:Frameworks & Extensions on jsfiddle.net

0
setTimeout(function(){ 
    isOverflowed(element)   
},500) 

function isOverflowed(element){ 
    return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth; 
} 

Esto se trabajó para mí. Gracias.

+1

¿En qué se diferencia esto de la respuesta de micnic? – carefulnow1

0

Esta es la solución jQuery que funcionó para mí. clientWidth etc. 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 los padres elementos tiene el ancho deseado (personalmente, tuve que usar parent().parent()). position es relativo a los padres. También he incluido extra_width porque mis elementos (" tags ") contienen imágenes que tienen poco tiempo para cargar, pero durante la llamada a la función que tiene la anchura cero, estropeando el cálculo para conseguir alrededor de eso, yo uso 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(); 
    } 
}); 

esperanza esto ayuda

18

Si desea mostrar solo un identificador para más contenido, puede hacerlo con CSS puro. Utilizo sombras de desplazamiento puro para esto. El truco es el uso de background-attachment: local;. El CSS se ve así:

.scrollbox { 
    overflow: auto; 
    width: 200px; 
    max-height: 200px; 
    margin: 50px auto; 

    background: 
    /* Shadow covers */ 
    linear-gradient(white 30%, rgba(255,255,255,0)), 
    linear-gradient(rgba(255,255,255,0), white 70%) 0 100%, 

    /* Shadows */ 
    radial-gradient(50% 0, farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)), 
    radial-gradient(50% 100%,farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%; 
    background: 
    /* Shadow covers */ 
    linear-gradient(white 30%, rgba(255,255,255,0)), 
    linear-gradient(rgba(255,255,255,0), white 70%) 0 100%, 

    /* Shadows */ 
    radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)), 
    radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%; 
    background-repeat: no-repeat; 
    background-color: white; 
    background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px; 

    /* Opera doesn't support this in the shorthand */ 
    background-attachment: local, local, scroll, scroll; 
} 

El código y un ejemplo se puede encontrar en http://dabblet.com/gist/2462915

y una explicación se puede encontrar aquí: http://lea.verou.me/2012/04/background-attachment-local/.

+0

awesome ** solución CSS simple ** –

+1

esto no es una respuesta para la pregunta –

+0

¡Esta es una de las cosas más locas que he visto con css! – Tim

Cuestiones relacionadas