451 votes

jQuery obtient la hauteur rendue d'un élément ?

Comment obtenir la hauteur rendue d'un élément ?

Disons que vous avez un <div> avec du contenu à l'intérieur. Ce contenu va étirer la hauteur de l'élément <div> . Comment obtenez-vous la hauteur "rendue" lorsque vous n'avez pas explicitement défini la hauteur. Évidemment, j'ai essayé :

var h = document.getElementById('someDiv').style.height;

Existe-t-il une astuce pour y parvenir ? J'utilise jQuery si cela peut aider.

0 votes

1301voto

strager Points 41713

Essayez-en un :

var h = document.getElementById('someDiv').clientHeight;
var h = document.getElementById('someDiv').offsetHeight;
var h = document.getElementById('someDiv').scrollHeight;

clientHeight comprend la hauteur et le rembourrage vertical.

offsetHeight comprend la hauteur, le rembourrage vertical et les bordures verticales.

scrollHeight comprend la hauteur du document contenu (qui serait supérieure à la simple hauteur en cas de défilement), le remplissage vertical et les bordures verticales.

3 votes

Merci, je ne connaissais pas cette propriété. Elle est également compatible avec IE8+.

0 votes

Je suis perplexe quant à la signification de clientHeight. J'ai un élément div qui contient un tas d'éléments p et le contenu va bien au-delà de la zone visible du navigateur vers le bas. Et je m'attendais à ce que clientHeight donne la hauteur rendue, et scrollHeight la longueur totale. Mais ils sont presque égaux (ils ne diffèrent que par la marge, le padding, etc.).

10 votes

@bahti à moins qu'il n'ait lui-même une hauteur limitée et un overflow:hidden ou une forme d'overflow:scroll, l'élément se développera (que ce soit dans votre vue ou non) pour montrer tout le contenu et scrollHeight et clientHeight seront égaux.

200voto

Russ Cam Points 58168

Il devrait juste être

$('#someDiv').height();

avec jQuery. Cela permet de récupérer la hauteur du premier élément de l'ensemble enveloppé sous forme de nombre.

Essayer d'utiliser

.style.height

ne fonctionne que si vous avez défini la propriété en premier lieu. Pas très utile !

1 votes

Un seul mot : génial ! Merci pour la participation de chacun. Beaucoup de bonnes informations sur ce fil. Cela me permettra de centrer les pages à l'aide de CSS, mais d'utiliser jQuery pour que la hauteur totale de la division "conteneur" soit correcte sans m'aventurer dans la jungle des CSS. Merci encore.

4 votes

Même si vous n'utilisez PAS jQuery ou si vous ne pouvez pas ou ne voulez pas le faire, je suggère fortement à toute personne qui met en œuvre ce système en utilisant seulement offsetHeight de télécharger la source de jQuery et de rechercher "height" pour trouver le code qu'ils utilisent. beaucoup de choses folles se passent là-dedans !

0 votes

Absolument d'accord avec cela Simon. Il est toujours intéressant d'étudier comment les bibliothèques Javascript apportent une solution à un problème.

51voto

pearl's Points 314

Vous pouvez utiliser .outerHeight() à cette fin.

Cela vous donnera la hauteur totale de l'élément. De plus, vous n'avez pas besoin de définir un paramètre css-height de l'élément. Par précaution, vous pouvez conserver sa hauteur auto afin qu'il puisse être rendu en fonction de la hauteur du contenu.

//if you need height of div excluding margin/padding/border
$('#someDiv').height();

//if you need height of div with padding but without border + margin
$('#someDiv').innerHeight();

// if you need height of div including padding and border
$('#someDiv').outerHeight();

//and at last for including border + margin + padding, can use
$('#someDiv').outerHeight(true);

Pour une vue claire de ces fonctions, vous pouvez aller sur le site de jQuery ou un poste détaillé ici .

il effacera le différence entre .height() / innerHeight() / outerHeight()

1 votes

Merci. En travaillant avec des flotteurs, j'ai eu beaucoup de problèmes avec la hauteur automatique, mais j'étais alors inexpérimenté. En général, je n'ai pas réglé la hauteur, sauf dans un script de mise en page complexe où je vide initialement le champ mais le règle pour qu'il soit égal pour chaque bloc (Div) qui finit par avoir le même haut. Même une différence d'un pixel entre les blocs peut foutre en l'air la mise en page lors du redimensionnement de Windows.

1 votes

BTW, je pense que l'offset a quelques utilisations dépendantes de la version du navigateur concernant les marges que cela élimine.

3 votes

La question ne fait pas appel à jQuery. Ugh.

15voto

Simon_Weaver Points 31141

Utiliser définitivement

$('#someDiv').height()   // to read it

ou

$('#someDiv').height(newHeight)  // to set it

Je poste ceci comme une réponse supplémentaire parce qu'il y a deux choses importantes que je viens d'apprendre.

J'ai failli tomber dans le piège à l'instant d'utiliser offsetHeight. Voici ce qui s'est passé :

  • J'ai utilisé la bonne vieille méthode consistant à utiliser un débogueur pour "observer" les propriétés de mon élément.
  • J'ai vu lequel a une valeur proche de celle que j'attendais.
  • C'était offsetHeight - donc je l'ai utilisé.
  • Puis j'ai réalisé que ça ne fonctionnait pas avec un DIV caché.
  • J'ai essayé de cacher après le calcul de maxHeight mais cela semblait maladroit - c'était le bazar.
  • J'ai fait une recherche - j'ai découvert jQuery.height() - et je l'ai utilisé.
  • J'ai découvert que height() fonctionne même sur les éléments cachés.
  • juste pour le plaisir, j'ai vérifié l'implémentation jQuery de la hauteur/largeur.

En voici une partie :

Math.max(
Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
Math.max(document.body["offset" + name], document.documentElement["offset" + name])
) 

Oui, il regarde à la fois le défilement et le décalage. Si cela ne fonctionne pas, il va encore plus loin, en prenant en compte les problèmes de compatibilité avec les navigateurs et les css. En d'autres termes, des choses dont je ne me soucie pas - ou dont je veux me soucier.

Mais je n'ai pas à le faire. Merci jQuery !

Morale de l'histoire : si jQuery a une méthode pour quelque chose, c'est probablement pour une bonne raison, probablement liée à la compatibilité.

Si vous n'avez pas lu le Liste des méthodes jQuery récemment, je vous suggère d'y jeter un coup d'œil.

0 votes

J'ai vu votre autre commentaire au niveau de la question. Je suis vendu sur jQuery. Je l'ai été pendant un petit moment. Mais ceci a scellé l'affaire. Je suis amoureux du fait que cette simple chose va résoudre des centaines de problèmes de mise en page pour moi (principalement sur les sites Intranet où je sais que JavaScript est exécuté).

8voto

DHorse Points 71

Alors, c'est la solution ?

"Si vous devez calculer quelque chose mais ne pas le montrer, définissez l'élément à visibility:hidden et position:absolute , l'ajouter à l'arbre DOM, obtenir le offsetHeight, et le supprimer. (C'est ce que la bibliothèque prototype fait derrière les lignes la dernière fois que j'ai vérifié)."

J'ai le même problème sur un certain nombre d'éléments. Il n'y a pas de jQuery ou de Prototype à utiliser sur le site mais je suis tout à fait d'accord pour emprunter cette technique si elle fonctionne. À titre d'exemple de ce qui n'a pas fonctionné, suivi de ce qui a fonctionné, j'ai le code suivant :

// Layout Height Get
function fnElementHeightMaxGet(DoScroll, DoBase, elementPassed, elementHeightDefault)
{
    var DoOffset = true;
    if (!elementPassed) { return 0; }
    if (!elementPassed.style) { return 0; }
    var thisHeight = 0;
    var heightBase = parseInt(elementPassed.style.height);
    var heightOffset = parseInt(elementPassed.offsetHeight);
    var heightScroll = parseInt(elementPassed.scrollHeight);
    var heightClient = parseInt(elementPassed.clientHeight);
    var heightNode = 0;
    var heightRects = 0;
    //
    if (DoBase) {
        if (heightBase > thisHeight) { thisHeight = heightBase; }
    }
    if (DoOffset) {
        if (heightOffset > thisHeight) { thisHeight = heightOffset; }
    }
    if (DoScroll) {
        if (heightScroll > thisHeight) { thisHeight = heightScroll; }
    }
    //
    if (thisHeight == 0) { thisHeight = heightClient; }
    //
    if (thisHeight == 0) { 
        // Dom Add:
        // all else failed so use the protype approach...
        var elBodyTempContainer = document.getElementById('BodyTempContainer');
        elBodyTempContainer.appendChild(elementPassed);
        heightNode = elBodyTempContainer.childNodes[0].offsetHeight;
        elBodyTempContainer.removeChild(elementPassed);
        if (heightNode > thisHeight) { thisHeight = heightNode; }
        //
        // Bounding Rect:
        // Or this approach...
        var clientRects = elementPassed.getClientRects();
        heightRects = clientRects.height;
        if (heightRects > thisHeight) { thisHeight = heightRects; }
    }
    //
    // Default height not appropriate here
    // if (thisHeight == 0) { thisHeight = elementHeightDefault; }
    if (thisHeight > 3000) {
        // ERROR
        thisHeight = 3000;
    }
    return thisHeight;
}

qui essaie tout et n'importe quoi pour obtenir un résultat nul. ClientHeight sans effet. Avec les éléments problématiques, j'obtiens généralement NaN pour la Base et zéro pour les hauteurs Offset et Scroll. J'ai ensuite essayé la solution Add DOM et clientRects pour voir si cela fonctionne ici.

29 juin 2011, J'ai effectivement mis à jour le code pour essayer à la fois l'ajout au DOM et le clientHeight avec de meilleurs résultats que prévu.

1) clientHeight était également de 0.

2) Dom m'a en fait donné une taille, ce qui était génial.

3) ClientRects retourne un résultat presque identique à la technique DOM.

Comme les éléments ajoutés sont fluides par nature, lorsqu'ils sont ajoutés à un élément DOM Temp autrement vide, ils sont rendus en fonction de la largeur de ce conteneur. Cela devient bizarre, parce que c'est 30px plus court qu'il ne l'est finalement.

J'ai ajouté quelques clichés pour illustrer comment la hauteur est calculée différemment. Menu block rendered normallyMenu block added to DOM Temp element

Les différences de taille sont évidentes. Je pourrais certainement ajouter le positionnement absolu et le masquage mais je suis sûr que cela n'aura aucun effet. Je continue à être convaincu que cela ne fonctionnera pas !

(Je m'écarte du sujet) La hauteur est inférieure à la hauteur réelle du rendu. Cela pourrait être résolu en définissant la largeur de l'élément DOM Temp pour qu'elle corresponde à celle du parent existant, ce qui pourrait être fait de manière assez précise en théorie. Je ne sais pas non plus ce qui se passerait si on les supprimait et qu'on les remettait à leur place. Comme ils sont arrivés par le biais d'une technique innerHTML, je chercherai à utiliser cette approche différente.

* CEPENDANT * Rien de tout cela n'était nécessaire. En fait, il a fonctionné comme annoncé et a renvoyé la hauteur correcte !!!

Lorsque j'ai pu rendre les menus visibles à nouveau, le DOM avait étonnamment renvoyé la hauteur correcte pour la mise en page fluide en haut de la page (279px). Le code ci-dessus utilise également getClientRects qui renvoie 280px.

Ceci est illustré dans l'instantané suivant (tiré de Chrome une fois en fonctionnement.)
enter image description here

Je n'ai aucune idée de la raison pour laquelle ce prototype fonctionne, mais ça semble être le cas. Sinon, getClientRects fonctionne également.

Je soupçonne que la cause de tous ces problèmes avec ces éléments particuliers était l'utilisation de innerHTML au lieu de appendChild, mais ce n'est que pure spéculation à ce stade.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X