Verifique com jquery se div tem elementos transbordantes

130

Eu tenho uma div com uma altura fixa e overflow:hidden;

Quero verificar com jQuery se a div tem elementos que estão excedendo a altura fixa da div. Como posso fazer isso?

Justin Meltzer
fonte
Eu posso estar errado, mas não acho que exista uma maneira mágica de jQuery para verificar se um elemento está fora de outro elemento. Você provavelmente teria que verificar a altura e a posição dos elementos dentro de sua div e fazer alguns cálculos para ver se eles transbordam.
adeneo
1
Sim, eu estava pensando em verificar se a diferença entre a posição da parte superior da div e a posição da parte inferior do último elemento filho dentro da div era maior que a altura da div
Justin Meltzer
Possível duplicado de detectar elementos de descarga usando jquery
Noyo

Respostas:

281

Na verdade, você não precisa de nenhum jQuery para verificar se há um estouro ou não. Usando element.offsetHeight, element.offsetWidth, element.scrollHeighte element.scrollWidthvocê pode determinar se o seu elemento tem maior índice do que o seu tamanho:

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

Veja o exemplo em ação: Fiddle

Mas se você quiser saber qual elemento dentro do seu elemento é visível ou não, precisará fazer mais cálculos. Existem três estados para um elemento filho em termos de visibilidade:

insira a descrição da imagem aqui

Se você deseja contar itens semi-visíveis, seria o script necessário:

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

}

E se você não quiser contar semi-visível, pode calcular com uma pequena diferença.

Mohsen
fonte
Corrija-me se estiver errado, mas isso não parece funcionar mais no Chrome V.20.0.1132.57. Se você mudar o texto dentro do div, a cor de fundo fica amarelo, jsbin.com/ujiwah/25/edit#javascript,html,live
Robbie
4
@Robbie <p>é um elemento de nível de bloco e ocupa 100% de largura. Se você quiser tentar isso com uma quantidade de texto dentro de p, basta fazer p{display:inline}. Dessa forma, o texto interno determina a largura de p.
Mohsen
Eu li "Você realmente não precisa de jQuery" e imediatamente disse "duh, é matemática simples".
Michael J. Calkins
1
Funciona na maioria dos casos, mas não vai encobrir cenário com tabelas CSS (-célula da tabela de exibição, mesa-RWO, mesa) -
Dmitry
Entendo que offsetHeight inclui bordas, que não contam para a área de rolagem. Apenas uma nota. (me corrija se eu estiver errado)
Lodewijk
38

Eu tinha a mesma pergunta que o OP, e nenhuma dessas respostas atendeu às minhas necessidades. Eu precisava de uma condição simples, para uma necessidade simples.

Aqui está a minha resposta:

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

Além disso, você pode mudar scrollWidthpor scrollHeightse você precisa testar a ambos os casos.

Sidney
fonte
1
Obrigado, isso funcionou para mim. só precisava de um exemplo simples em jquery, mas não em js simples.
Mikhail-t
4
não funciona para elementos com preenchimento / margem. uso outerWidth (true) instread de largura
Vladimir Shmidt
Não funciona, isto é, funciona bem no mozilla e no chrome.
Sushil Kumar #
Eu tenho alguns efeitos estranhos com este script. Testando no Chrome. Eu o reescrevi para verificar a altura (usando OuterHeight) e se eu usar F5 para recarregar uma página para verificar o script ou navegar para outra página, ela sempre retornará como estouro = true, mas se eu usar o ctrl-F5, ele será de volta como estouro = falso. É quando testamos uma situação que deveria retornar falsa. Quando é suposto ser verdade, sempre funciona.
Dennis
Ok, eu mesmo descobri. Eu tenho minhas tags de script agrupadas em window.addEventListener ('DOMContentLoaded'), para que funcionem com meu jquery carregado de forma assíncrona e outros arquivos. Porém, a execução desse script nesse estágio retorna leituras aparentemente falsas; portanto, para esse script, substitui DOMContentLoaded por apenas 'load' para atrasar ainda mais a execução do script. Agora ele retorna resultados corretos sempre. E, para os meus propósitos, é perfeitamente bom que espere executá-lo até depois que a página for carregada, então posso adicionar uma animação para destacar a atenção dos usuários em um botão "leia mais".
Dennis
4

Então, eu usei a biblioteca jquery transbordante: https://github.com/kevinmarx/overflowing

Depois de instalar a biblioteca, se você deseja atribuir a classe overflowinga todos os elementos que estão excedendo, basta executar:

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

Isso dará à classe overflowing, como <div class="targetElement overflowing">todos os elementos que estão transbordando. Você pode adicionar isso a algum manipulador de eventos (clique, mouseover) ou outra função que executará o código acima para que ele seja atualizado dinamicamente.

maudulus
fonte
3

Parcialmente baseado na resposta de Mohsen (a primeira condição adicionada cobre o caso em que a criança está oculta diante dos pais):

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

Então faça:

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

Um método é verificar o scrollTop contra ele mesmo. Atribua ao conteúdo um valor de rolagem maior que seu tamanho e verifique se o scrollTop é 0 ou não (se não for 0, o excesso está excedido).

http://jsfiddle.net/ukvBf/

Joseph Marikle
fonte
1

Em inglês simples: obtenha o elemento pai. Verifique a altura e salve esse valor. Em seguida, percorra todos os elementos filhos e verifique suas alturas individuais.

Isso está sujo, mas você pode ter a idéia básica: http://jsfiddle.net/VgDgz/

Doozer Blake
fonte
1
É um bom exemplo, mas e a posição. Se um elemento for posicionado absoluto até o topo do pai, ele poderá transbordar, mesmo que a altura seja menor que o pai.
adeneo
Absolutamente, provavelmente existem alguns casos diferentes que poderiam causar isso. Apenas um exemplo rápido de onde começar. O caso específico do Op provavelmente definirá o que precisa ser verificado
Doozer Blake 5/05
0

Aqui está uma solução jQuery pura, mas é bastante confusa:

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
fonte
0

Esta é a solução jQuery que funcionou para mim. offsetWidthetc não funcionou.

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

Se isso não funcionar, verifique se o pai dos elementos tem a largura desejada (pessoalmente, eu tive que usar parent().parent()). positionÉ relativo ao pai. Também incluí extra_widthporque meus elementos ("tags") contêm imagens que levam pouco tempo para serem usadas . load, mas durante a chamada de função eles têm largura zero, estragando o cálculo.Para contornar isso, eu uso o seguinte código de chamada:

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 isto ajude.

Dennis Golomazov
fonte
0

Corrigi isso adicionando outra div na que estourou. Então você compara as alturas dos 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>

e os js

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

Parece mais fácil ...

alex toader
fonte