web-dev-qa-db-fra.com

Besoin de trouver la hauteur de la div cachée sur la page (définie pour afficher: aucune)

Je dois mesurer la hauteur offset d'une div qui se trouve à l'intérieur d'un élément caché.

<div id="parent" style="display: none;">
    <div id="child">Lorem Ipsum dolor sit amet.</div>
</div>

Le parent div doit être défini sur "display:none". Je n'ai aucun contrôle sur cela. Je me rends compte que l'offsetHaut de l'enfant div va être 0. Je dois trouver une solution de contournement.

Quelque chose avec lequel j'ai joué est lorsque la page se charge, je copie les noeuds parent du parent, injecte une div sur la page qui est définie sur "visiblity:hidden". Ensuite, je mesure la hauteur de ces éléments et supprime les nœuds une fois l'opération terminée. 

D'autres pensées?

Mise à jour: Voici ce que j'ai dû faire:

À l’aide de YUI 2, lors du chargement de la page, j’ai trouvé tous les éléments de ce nom de classe donné qui étaient configurés pour afficher: aucun, ou dont la hauteur et la largeur étaient égales à 0 (c’est une façon de déterminer si un élément existe ou si un parent est défini pour afficher :aucun). J'ai ensuite défini cet élément pour afficher: bloc. J'ai ensuite vérifié la même chose chez son parent et ai montré aux parents jusqu'à ce qu'il trouve un parent visible. Une fois l'affichage le plus élevé: aucun ancêtre n'est configuré pour afficher: bloc, je peux mesurer mon élément.

Une fois que tous les éléments ont été mesurés, je les ai tous réinitialisés: aucun.

21
Jamis Charles

Vous devez rendre le parent de l'élément visible pour ce moment très court pendant que vous obtenez les dimensions de l'élément. Dans une solution générique, tous les ancêtres sont généralement traversés et rendus visibles. Ensuite, leurs valeurs display sont remises aux valeurs originales.

Il y a bien sûr des problèmes de performances. 

Nous avons envisagé cette approche dans l'implémentation de Prototype.js, mais nous avons fini par getWidth et getHeight rendant uniquement l'élément réel visible , sans traverser les ancêtres. 

Le problème des solutions alternatives, telles que le retrait d'éléments d'un parent "caché" - est que certains styles peuvent ne plus s'appliquer à un élément une fois qu'il est sorti de sa hiérarchie "normale". Si vous avez une structure comme celle-ci:

<div class="foo" style="display:none;">
  <div class="bar">...</div>
</div>

et ces règles:

.bar { width: 10em; }
.foo .bar { width: 15em; }

puis retirer un élément de son parent entraînera de fausses dimensions.

21
kangax

Vous pouvez cloner l'élément, le positionner absolument à -10000, -10000, mesurer le clone et le détruire.

15
lod3n

Fait une solution js pure sans Jquery et sans clonage (ce qui, je suppose, est plus rapide)

var getHeight = function(el) {
    var el_style      = window.getComputedStyle(el),
        el_display    = el_style.display,
        el_position   = el_style.position,
        el_visibility = el_style.visibility,
        el_max_height = el_style.maxHeight.replace('px', '').replace('%', ''),

        wanted_height = 0;

    // if its not hidden we just return normal height
    if(el_display !== 'none' && el_max_height !== '0') {
        return el.offsetHeight;
    }

    // the element is hidden so:
    // making the el block so we can meassure its height but still be hidden
    el.style.position   = 'absolute';
    el.style.visibility = 'hidden';
    el.style.display    = 'block';

    wanted_height     = el.offsetHeight;

    // reverting to the original values
    el.style.display    = el_display;
    el.style.position   = el_position;
    el.style.visibility = el_visibility;

    return wanted_height;
}

voici la démo https://jsfiddle.net/xuumzf9k/1/

S'il vous plaît laissez-moi savoir si vous pouvez trouver des améliorations à cela (comme je l'utilise dans mes projets principaux)

11
Symba

Si vous utilisez style.display = "none", l'élément aura 0 largeur et hauteur,
mais en utilisant style.visibility = "hidden", l'élément aura la largeur et la hauteur calculées par le navigateur (comme d'habitude).

9

Alors voici la solution jQuery qui fonctionne basée sur la réponse de lod3n et avec l'aide du commentaire de 999: 

 var getHiddenElementHeight = fonction (élément) {
 var tempId = 'tmp -' + Math.floor (Math.random () * 99999); // génère un identifiant unique juste au cas où 
 $ (element) .clone () 
 .css ('position', 'absolu') 
 .css ('hauteur', 'auto'). css ('largeur', ' 1000px ') 
 // injecte directement dans l'élément parent de sorte que tous les css s'appliquent (oui, je le sais, sauf le: premier enfant et d'autres pseudo-trucs .. 
 .AppendTo ($ (element) .parent ()) 
 .css ('left', '- 10000em') 
 .addClass (tempId) .show () 
 h = $ ('.' + tempId ) .height () 
 $ ('.' + tempId) .remove () 
 renvoyer h; 
} 

Prendre plaisir!

4
dsomnus

Donc, vous ne pouvez même pas changer le display:none; en height:0; overflow:hidden;? Peut-être que vous pourriez remplacer cela dans votre propre feuille de style comme ceci:

div#parent { display: block !important; height:0; overflow:hidden; }

Et puis, comme vous utilisez YUI (en supposant que YUI 2), vous pouvez utiliser ceci:

var region = YAHOO.util.Dom.getRegion('child');

Pour obtenir les dimensions et le décalage de l'enfant.

1
Max

Jusqu'à ce que l'élément soit rendu, il n'a pas de hauteur. Même si vous clonez l'objet parent et que vous l'affichez quelque part que l'utilisateur ne peut pas voir, rien ne garantit que le clone aura la même hauteur que la taille finale de l'objet masqué.

Beaucoup de choses peuvent affecter la hauteur qui ne serait pas nécessairement restituée dans le clone - tout élément du DOM et son interaction avec les règles CSS pourraient modifier le rendu de tout autre élément du DOM. À moins de cloner l'intégralité du document (et même si cela n'est pas infaillible), vous n'avez aucun moyen de déterminer la hauteur de l'objet masqué.

Si vous devez connaissez la hauteur avant qu'elle ne soit affichée à l'utilisateur, vous devrez la "pirater" en l'affichant aussi rapidement que possible, puis en la cachant à nouveau. Très probablement, l'utilisateur verra ce hoquet et ne sera pas ravi du résultat.

1
Brandon Belvin

Essayez d'utiliser:

#parent{ display:block !important; visibility:hidden; position:absolute} 
1
emelendez

Utilisez z-index pour masquer un élément sous un élément non transparent, le montrer et obtenir une hauteur.

0
Anatoliy

Voici ce que j'ai fini par devoir faire: 

À l’aide de YUI 2, lors du chargement de la page, j’ai trouvé tous les éléments de ce nom de classe donné qui étaient configurés pour afficher: aucun, ou dont la hauteur et la largeur étaient égales à 0 (c’est une façon de déterminer si un élément existe ou si un parent est défini pour afficher :aucun). J'ai ensuite défini cet élément pour afficher: bloc. J'ai ensuite vérifié la même chose chez son parent et ai montré aux parents jusqu'à ce qu'il trouve un parent visible. Une fois l'affichage le plus élevé: aucun ancêtre n'est configuré pour afficher: bloc, je peux mesurer mon élément.

Une fois que tous les éléments ont été mesurés, je les ai tous réinitialisés: aucun.

0
Jamis Charles