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.
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.)
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.
0 votes
Voir cette réponse stackoverflow.com/questions/19581307/