web-dev-qa-db-fra.com

Comment masquer des éléments avec jQuery avant qu'ils ne soient rendus?

Je veux générer une mise en page html avec des zones (divs, travées) qui peuvent être affichées/masquées de manière conditionnelle. Ces zones sont masquées par défaut.

Si j'appelle la méthode .hide () avec jquery sur document.ready, ces zones peuvent clignoter (les navigateurs rendent les documents partiellement chargés). J'applique donc le style "display: none" dans la mise en page html.

Je me demande quelle est la meilleure pratique pour éviter de clignoter, car l'application de "display: none" enfreint la règle d'incapsulation - je sais ce que jquery fait avec hide/show et l'utilise. Si l'implémentation de masquage/affichage de jquery changera un jour, je ne pourrai pas utiliser tout le site.

Merci d'avance

44
Andrew Florko

Il n'y a absolument rien de mal à définir une propriété d'affichage initiale d'un élément, surtout si vous l'encapsulez dans une classe CSS.

3
James H

@Andrew,

Je sais que la réponse a déjà été acceptée, mais en utilisant display: none; sera un cauchemar pour les utilisateurs sans Javascript.

En utilisant Javascript en ligne, vous pouvez masquer un élément sans qu'il clignote. Les utilisateurs sans Javascript pourront toujours le voir.

Considérez quelques divs qui devraient être cachées lors du chargement de la page.

<head>
    <script type="text/javascript" src="jQuery.js"></script>
</head>
<body>
    <div id="hide-me">
        ... some content ...
    </div>
    <script type="text/javascript">
        $("#hide-me").hide();
    </script>

    <div id="hide-me-too">
        ... some content ...
    </div>
    <script type="text/javascript">
        $("#hide-me-too").hide();
    </script>
</body>

Le Javascript en ligne s'exécutera dès que l'élément sera rendu, le cachant ainsi à l'utilisateur.

33
Marko

Je suis d'accord avec Boris Guéry, qu'il ne s'agit pas d'une ingénierie excessive, mais plutôt d'une meilleure pratique standard. J'irais d'une manière légèrement différente de Boris, en ajoutant une classe no-js au html au départ, puis en la supprimant avec JavaScript.

De cette façon, vous n'attendez pas que le document soit prêt à masquer le contenu, et sans JavaScript, vous voyez toujours le contenu. Supposer que l'utilisateur n'a pas JavaScript est plus conforme à la philosophie de l'amélioration progressive.

ex:

<html class="no-js">
<body>
<div id="foo"></div>
</body>
</html>

mon css:

#foo {
    display: none;
}
html.no-js #foo {
    display: block;
}

et javascript

$(document).ready(
   function()
   {
     $('html').removeClass('no-js');
   }
);

********* OR au cas par cas ***********

ex:

<div class="no-js" id="foo">foobar and stuff</div>

css:

.no-js {
  display:none;
}
#foo {
  display: block;
}
#foo.no-js {
  display: none;
}

js:

$(document).ready(function(){
  // remove the class from any element that has it.
  $('.no-js').removeClass('no-js');
});
6
Ryan Ore

Je règle généralement une classe .js sur mon élément pour définir la propriété appropriée lorsque javascript est activé.

Je peux ensuite définir le CSS selon que javascript est présent ou non.

ex:

<html class="js">
<body>
<div id="foo"></div>
</body>
</html>

mon css:

html.js #foo
{
    display: none;
}

et javascript

$(document).ready(
   function()
   {
     $(html).addClass('js');
   }
);
4
Boris Guéry

Pourquoi ne pas faire ça?:

// Hide HTML element ASAP
$('html').hide();

// DOM-ready function
$(function () {
   // Do stuff with the DOM, if needed
   // ...

   // Show HTML element
   $('html').show();
}

Cela semble marcher correctement!

Cordialement.

3
Andy

J'ai également eu du mal avec cela, en particulier dans IE, et j'ai trouvé cela très utile: http://robertnyman.com/2008/05/13/how-to-hide-and-show-initial-content-depending -si-si-le-support-javascript-est-disponible /

3
tester testers

vous pouvez appliquer "display: none" dans une classe CSS.

Parce que l'ordre dans lequel un navigateur doit lire du code HTML pour que JavaScript trouve l'élément. Vous devez marquer l'élément comme masqué lorsque le navigateur lit votre code HTML.

Cependant, vous pouvez également insérer le code HTML dans votre JavaScript et vous pouvez appeler hide avant qu'il ne soit rendu.

1
Darkerstar

J'utiliserais toujours Modernizr.js http://modernizr.com/ pour gérer cela.

Avec Mondernizr, une classe 'js' ou 'no-js' est ajoutée à la balise HTML de votre page.

De là, vous ne pouvez masquer vos éléments que si la balise html a la classe js.

Modernizr est idéal pour de nombreuses autres applications et mérite d'être lu si vous ne l'avez pas utilisé auparavant: http://modernizr.com/docs/

0
Jimbo Jones

Ce que je fais toujours, c'est créer un div vide. Et si certaines données à l'intérieur de ce composant doivent être affichées, je charge des données de manière asynchrone (c'est-à-dire html) en utilisant $ .ajax ().

Pas besoin d'une lib supplémentaire.

0
Coen Damen

Voici ma suggestion. Il utilise cette solution pour créer une nouvelle règle CSS. L'essentiel: une classe CSS qui cache du html sera créée si JS est disponible, sinon non. Et cela se produit avant le contenu principal (avec les parties html qui devraient être initialement cachées) soit traité!

<html>
<head>
    <style>
        /* This class gets overwritten if JS is enabled. If a css file (bootstrap, ...) 
        gets loaded with such a class this would be also overwritten. This solution does 
        not require the class. It is here just to show that it has no effect 
        if JS is activated.*/
        .hidden {
            display: block;
            background: red;
        }
    </style>
    <script>
        // this is copied from the linked stackoverflow reply:
        function setStyle(cssText) {
            var sheet  = document.createElement('style');
            sheet.type = 'text/css';
            /* Optional */
            window.customSheet = sheet;
            (document.head || document.getElementsByTagName('head')[0]).appendChild(sheet);
            return (setStyle = function (cssText, node) {
                if (!node || node.parentNode !== sheet)
                    return sheet.appendChild(document.createTextNode(cssText));
                node.nodeValue = cssText;
                return node;
            })(cssText);
        }

        // And now: This class only gets defined if JS is enabled. Otherwise 
        // it will not be created/overwritten.
        setStyle('.hidden { display: none; }');

        // Attention: Now that the class is defined it could be overwritten 
        // in other CSS declarations (in style tags or with loaded CSS files).
    </script>
</head>
<body>

    <button>Show/Hide</button>

    <div class="">before</div>
    <div class="my-element hidden">
        Content that should be initially hidden if possible.
        You may want to multiply this div by some thousands
        so that you see the effect. With and without JS enabled.
    </div>
    <div class="">after</div>

    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
    <script>
        // Here is some 'normal' JS code. Very likely loaded as a JS file:
        $('button').click(function () {
            $('.my-element').toggleClass('hidden');
            // or setting display directly: 
            //   $('.my-element').toggle() 
            // but well, having class hidden though it is not 
            // hidden makes is not so Nice...
        })
    </script>

</body>
</html>

Un peu plus compliqué, mais je pense que c'est une bonne solution. L'avantage est que le scintillement est empêché et qu'il fonctionne si JS n'est pas activé. Et cela ne nécessite pas jQuery.

0
robsch

Après un certain temps de réflexion, j'ai eu l'idée de la solution suivante. Par rapport à mon autre solution je l'ai réduit à l'essentiel (et utilisé ce pour ajouter une classe par JS):

<html>
<head>
    <style>
        /* This could be also part of an css file: */
        .container-with-hidden-elements .element {
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <script>
            document.getElementsByClassName('container')[0]
                    .className += ' container-with-hidden-elements';
        </script>

        <div class="element">Content that should be initially hidden if possible.</div>
    </div>
</body>
</html>

La balise de script est exécutée immédiatement et ajoute une classe à un conteneur. Dans ce conteneur, certains éléments imbriqués sont désormais masqués car le conteneur a la classe spéciale et il existe une règle CSS qui a maintenant un effet.

Encore une fois, cela se produit avant que le code HTML restant ne soit traité (empêche de clignoter). Et aussi, si JS est désactivé, tous les éléments sont visiblement par défaut - ce qu'on peut appeler amélioration progressive .

Je ne sais pas si cela fonctionne dans tous les navigateurs. Mais l'OMI, ce serait une solution simple et soignée.

0
robsch

Il existe de nombreuses réponses, vous pouvez utiliser la méthode show () et coder la condition à afficher ou à masquer. Voici l'exemple de code show_hide lorsque le rendu est terminé

  <div id="banner-message">
  <p id="hello">Hello World!!!!!</p>
  <input id="statusconf" value="" type="checkbox">Show hello world text when i click this check box
  <button>Change color</button>
</div>

    // find elements
var banner = $("#banner-message")
var button = $("button")

// handle click and add class
button.on("click", function(){
  banner.addClass("alt")
})

//Set this up as part of document ready if you wish
//$(document).ready(function(e) {

    $("#statusconf").show(function(e) {
            if ($("#statusconf").is(':checked') === false) {
                $('#hello').hide();
            } else {
        $("#hello").show();
      }
  });

    $("#statusconf").on("click", function(e) {
    if ($("#statusconf").is(':checked') === false) {
                $('#hello').hide();
            } else {
        $("#hello").show();
      }
  });

//});
0
webjockey