Vérifiez avec jquery si div a des éléments débordants

130

J'ai un div avec une hauteur fixe et overflow:hidden;

Je veux vérifier avec jQuery si le div a des éléments qui débordent au-delà de la hauteur fixe du div. Comment puis-je faire ceci?

Justin Meltzer
la source
Je peux me tromper, mais je ne pense pas qu'il existe un moyen magique de jQuery de vérifier si un élément est en dehors d'un autre élément. Vous devrez probablement vérifier la hauteur et la position des éléments à l'intérieur de votre div et faire quelques calculs pour voir s'ils débordent.
adeneo
1
Ouais, je pensais vérifier si la différence entre la position du haut du div et la position du bas du dernier élément enfant à l'intérieur du div était supérieure à la hauteur du div
Justin Meltzer
Possible duplication du débordement des éléments
Noyo

Réponses:

281

En fait, vous n'avez pas besoin de jQuery pour vérifier s'il y a un débordement ou non. En utilisant element.offsetHeight, element.offsetWidth, element.scrollHeightet element.scrollWidthvous pouvez déterminer si ont un contenu plus grand que la taille de ce votre élément:

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

Voir l'exemple en action: Fiddle

Mais si vous voulez savoir quel élément à l'intérieur de votre élément est visible ou non, vous devez faire plus de calcul. Il existe trois états pour un élément enfant en termes de visibilité:

entrez la description de l'image ici

Si vous voulez compter les éléments semi-visibles, ce serait le script dont vous avez besoin:

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

}

Et si vous ne voulez pas compter semi-visible, vous pouvez calculer avec une petite différence.

Mohsen
la source
Corrigez-moi si je me trompe, mais cela ne semble plus fonctionner Chrome V.20.0.1132.57. Si vous modifiez le texte à l'intérieur du div, la couleur d'arrière-plan reste jaune, jsbin.com/ujiwah/25/edit#javascript,html,live
Robbie
4
@Robbie <p>est un élément de niveau bloc et prend 100% de largeur. Si vous voulez essayer cela avec une quantité de texte à l'intérieur du p, faites simplement p{display:inline}. De cette façon, le texte à l'intérieur détermine la largeur de p.
Mohsen
J'ai lu "Vous n'avez en fait pas besoin de jQuery" et je suis immédiatement allé "duh, c'est simple math."
Michael J. Calkins
1
Fonctionne dans la plupart des cas mais ne couvrira pas le scénario avec des tableaux CSS (display table-cell, table-rwo, table) -
Dmitry
Je comprends que offsetHeight inclut des bordures, qui ne comptent pas dans la zone de défilement. Juste une note. (corrigez-moi si je me trompe)
Lodewijk
38

J'avais la même question que l'OP, et aucune de ces réponses ne correspondait à mes besoins. J'avais besoin d'une condition simple, pour un simple besoin.

Voici ma réponse:

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

En outre, vous pouvez changer scrollWidthde scrollHeightsi vous avez besoin de tester l' une ou l' autre cas.

Sidney
la source
1
Merci, cela a fonctionné pour moi. juste besoin d'un exemple simple dans jquery mais pas dans js ordinaire.
mikhail-t
4
ne fonctionne pas pour les éléments avec remplissage / marge. utiliser externalWidth (true) au lieu de width
Vladimir Shmidt
Ne fonctionne pas dans ie, fonctionne très bien dans Mozilla et Chrome.
Sushil Kumar
J'ai des effets étranges avec ce script. Test dans Chrome. Je l'ai réécrit pour vérifier la hauteur (en utilisant OuterHeight) et si j'utilise F5 pour recharger une page pour vérifier le script, ou pour y accéder à partir d'une autre page, il revient toujours comme overflow = true, mais si j'utilise ctrl-F5, cela vient retour en tant que débordement = faux. C'est lors du test d'une situation censée revenir fausse. Quand c'est censé être vrai, ça marche toujours.
Dennis
Ok je l'ai compris moi-même. J'ai mes balises de script enveloppées dans window.addEventListener ('DOMContentLoaded') afin qu'elles fonctionnent avec mon jquery chargé de manière asynchrone et d'autres fichiers. Mais exécuter ce script à ce stade renvoie des lectures apparemment fausses, donc pour ce script, j'ai remplacé DOMContentLoaded par juste "load" pour retarder davantage l'exécution du script. Maintenant, il renvoie des résultats corrects à chaque fois. Et pour mes besoins, c'est parfaitement bien qu'il attende de l'exécuter jusqu'à ce que la page soit chargée, alors je peux même ajouter une animation pour mettre en évidence l'attention des utilisateurs sur un bouton "en savoir plus".
Dennis
4

J'ai donc utilisé la bibliothèque jquery débordante: https://github.com/kevinmarx/overflowing

Après avoir installé la bibliothèque, si vous souhaitez affecter la classe overflowingà tous les éléments débordants, vous exécutez simplement:

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

Cela donnera alors la classe overflowing, comme <div class="targetElement overflowing">pour tous les éléments qui débordent. Vous pouvez ensuite l'ajouter à un gestionnaire d'événements (clic, survol de la souris) ou à une autre fonction qui exécutera le code ci-dessus afin qu'il se mette à jour dynamiquement.

maudulus
la source
3

Partiellement basé sur la réponse de Mohsen (la première condition ajoutée couvre le cas où l'enfant est caché devant le parent):

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

Alors faites simplement:

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

Une méthode consiste à vérifier scrollTop par rapport à lui-même. Donnez au contenu une valeur de défilement plus grande que sa taille, puis vérifiez si son scrollTop est 0 ou non (s'il n'est pas 0, il a un débordement).

http://jsfiddle.net/ukvBf/

Joseph Marikle
la source
1

En anglais simple: obtenez l'élément parent. Vérifiez sa hauteur et enregistrez cette valeur. Ensuite, parcourez tous les éléments enfants et vérifiez leurs hauteurs individuelles.

C'est sale, mais vous pourriez avoir l'idée de base: http://jsfiddle.net/VgDgz/

Doozer Blake
la source
1
C'est un bon exemple, mais qu'en est-il du poste. Si un élément est positionné de manière absolue tout en haut du parent, il peut déborder même si la hauteur est inférieure au parent.
adeneo
Absolument, il y a probablement plusieurs cas différents qui pourraient en être la cause. Juste un exemple rapide de par où commencer. Le cas spécifique d'Op définira probablement ce qui doit être vérifié
Doozer Blake
0

Voici une solution jQuery pure, mais elle est plutôt compliquée:

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
la source
0

C'est la solution jQuery qui a fonctionné pour moi. offsetWidthetc. n'a pas fonctionné.

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

Si cela ne fonctionne pas, assurez-vous que le parent des éléments a la largeur souhaitée (personnellement, j'ai dû utiliser parent().parent()). positionEst relatif au parent. J'ai également inclus extra_widthparce que mes éléments ("balises") contiennent des images qui prennent peu de temps à charge, mais pendant l'appel de fonction, ils ont une largeur nulle, ce qui gâche le calcul. Pour contourner cela, j'utilise le code d'appel suivant:

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

J'espère que cela t'aides.

Dennis Golomazov
la source
0

J'ai corrigé cela en ajoutant un autre div dans celui qui déborde. Ensuite, vous comparez les hauteurs des 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>

et le js

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

Cela semble plus facile ...

alex toader
la source