Est-ce donc la réponse?
"Si vous devez calculer quelque chose sans le montrer, définissez l'élément sur visibility:hidden
etposition:absolute
ajoutez-le à l'arborescence DOM, récupérez l'offsetHeight et supprimez-le. (C'est ce que fait la bibliothèque de prototypes 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 la technique si ça marche. Comme exemple de certaines choses qui n'ont pas fonctionné, suivies 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, je reçois généralement NaN dans la base et zéro dans les hauteurs de décalage et de défilement. J'ai ensuite essayé la solution Ajouter DOM et clientRects pour voir si cela fonctionne ici.
29 juin 2011, j'ai en effet mis à jour le code pour essayer à la fois d'ajouter à DOM et clientHeight avec de meilleurs résultats que ce à quoi je m'attendais.
1) clientHeight était également égal à 0.
2) Dom m'a en fait donné une hauteur qui était super.
3) ClientRects renvoie un résultat presque identique à la technique DOM.
Étant donné que les éléments ajoutés sont de nature fluide, 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, car c'est 30 pixels plus court qu'il ne finit par le faire.
J'ai ajouté quelques instantanés pour illustrer comment la hauteur est calculée différemment.
Les différences de hauteur sont évidentes. Je pourrais certainement ajouter un positionnement absolu et caché mais je suis sûr que cela n'aura aucun effet. J'ai continué à être convaincu que cela ne fonctionnerait pas!
(Je m'éloigne davantage) La hauteur sort (rend) plus bas que la vraie hauteur rendue. Cela pourrait être résolu en définissant la largeur de l'élément DOM Temp pour qu'il corresponde au parent existant et pourrait être fait assez précisément en théorie. Je ne sais pas non plus ce qui résulterait de leur suppression et de leur ajout à leur emplacement actuel. Comme ils sont arrivés par une technique innerHTML, je chercherai à utiliser cette approche différente.
* CEPENDANT * Rien de tout cela n'était nécessaire. En fait, cela a fonctionné comme annoncé et a retourné la bonne hauteur !!!
Quand j'ai été en mesure de rendre les menus à nouveau incroyablement visibles, DOM avait renvoyé la bonne hauteur selon la disposition fluide en haut de la page (279 px). Le code ci-dessus utilise également getClientRects qui retourne 280 px.
Ceci est illustré dans l'instantané suivant (extrait de Chrome une fois qu'il a fonctionné.)
Maintenant, je n'ai aucune idée de pourquoi ce truc de prototype fonctionne, mais il semble que ce soit le cas. Alternativement, 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 d'appendChild, mais c'est de la pure spéculation à ce stade.