2010-05-10 10 views
42

Ich möchte HTML-Layout mit Bereichen (divs, span) generieren, die bedingt/versteckt werden können. Diese Bereiche sind standardmäßig ausgeblendet.Wie Elemente mit jQuery ausblenden, bevor sie gerendert werden?

Wenn ich .hide() Methode mit jquery auf document.ready aufrufen, können diese Bereiche blinken (Browser übertragen teilweise geladene Dokumente). Also wende ich "display: none" -Stil im HTML-Layout an.

Ich frage mich, was ist die beste Praxis, um zu vermeiden, zu blinken, weil die Anwendung "display: none" bricht incapsulation Regel - Ich weiß, was jquery mit hide/show tut und es verwendet. Wenn sich die Implementierung von JQuery eines Tages ändert, wird die gesamte Site nicht mehr funktionieren.

Vielen Dank im Voraus

Antwort

0

Es gibt absolut nichts falsch mit einer intial Anzeige Eigenschaft eines Elements einstellen, vor allem, wenn Sie kapseln es in einer CSS-Klasse.

+23

Wenn Sie diesen Weg gehen, wird ein Browser mit deaktiviertem JavaScript diese Elemente nie –

+8

nie, jemals, jemals überhaupt. Das ist schlechte Praxis. – Marko

+1

Es gibt keine "CSS-Klasse". –

3

ich in der Regel eine Js-Klasse zu meinem Elemente stellen Sie die richtige Eigenschaft zu setzen, wenn Javascript aktiviert ist.

Ich kann dann das CSS abhängig davon setzen, ob Javascript vorhanden ist oder nicht.

ex:

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

mein css:

html.js #foo 
{ 
    display: none; 
} 

und Javascript

$(document).ready(
    function() 
    { 
    $(html).addClass('js'); 
    } 
); 
+0

Vielen Dank, aber ich beschloss, meine Wahl auf Simple-CSS zu stoppen und fand diese gemischte (CSS + Javascript) Ansatz für meine Aufgaben overengineered. –

+1

Das Interesse ist, Verwendbarkeit und Zugänglichkeit für Leute zu halten, die Javascript nicht haben, wenn Sie Ihren Block mit seiner Identifikation zusammenbringen, ist es wahrscheinlich für Leute versteckt, die nicht Javascript aktiviert haben. Sie wollten die Best Practices kennen, es ist eine Best Practice. –

1

können Sie "display: none" in einer CSS-Klasse anwenden.

Weil die Reihenfolge, in der ein Browser etwas HTML-Code lesen muss, damit das JavaScript das Element findet. Sie müssen das Element ausgeblendet markieren, da der Browser Ihren HTML-Code liest.

Wie auch immer Sie den HTML-Code in Ihr JavaScript einfügen können, und Sie können ausblenden aufrufen, bevor es gerendert wird. Auch

+0

Danke, ich entschied mich, "display: none" mit CSS –

31

@ Andrew,

Ich weiß, dass die Antwort bereits akzeptiert worden, aber display: none; Verwendung wird ein Alptraum Benutzer ohne Javascript.

Mit Inline-Javascript können Sie ein Element ausblenden, ohne dass es jemals blinkt. Benutzer ohne Javascript können es trotzdem sehen.

Betrachten Sie einige Divs, die beim Laden der Seite ausgeblendet werden sollten.

Das Inline-Javascript wird ausgeführt, sobald das Element gerendert wird, wodurch es vor dem Benutzer verborgen wird.

+12

Das funktioniert ohne zu blinken (in allen Browsern, für jede Seite) ist einfach nicht wahr ... Verschiedene Browser, je nach ihrer genauen Umsetzung und der Größe der Seite, kann am Ende "blinken" oder sogar den Inhalt für eine Weile anzeigen. EG Beispiel (1 MB), das für eine Weile in Chrome angezeigt wird: http://www.architectshack.com/as/BlinkTest.ashx?2 – Tao

+0

Vereinbarte Tao - das funktioniert nicht in einigen Browsern, einschließlich Chrome. – jimasp

5

Ich stimme Boris Guéry zu, dass es nicht Über-Engineering ist, sondern eine Standard Best Practice. Ich würde einen etwas anderen Weg gehen als Boris, indem ich zuerst eine no-js-Klasse zum html hinzufüge und sie dann mit JavaScript entferne.

Auf diese Weise warten Sie nicht darauf, dass das Dokument bereit ist, den Inhalt zu verbergen, und ohne JavaScript sehen Sie immer noch den Inhalt. Vorausgesetzt, der Benutzer hat kein JavaScript mehr im Einklang mit der Philosophie der progressiven Verbesserung.

ex:

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

mein css:

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

und Javascript

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

********* OR auf einer pro-Fall Basis ***********

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'); 
}); 
+0

+1 Ich mag die Idee dazu sehr. Allerdings kann ich mit einem CMS nicht nur das HTML-Tag bearbeiten. Ich frage mich, ob es eine andere Lösung gibt. – Tom

+0

Es muss nicht das html-Tag sein, das ist nur das breiteste Netz. Kannst du Klassen zu etwas hinzufügen? Wenn ja, dann können Sie es auf Einzelfallbasis machen, dann entfernen Sie im Javascript die Klasse .no-js von allen Objekten, die es haben. Ich werde meine Antwort mit einem Vorschlag aktualisieren. –

+0

, damit es funktioniert, endete meine Skriptdatei so, so dass removeClass() früh ausgelöst wird und show() spät ausgelöst wird: $ ('html'). RemoveClass ('no-js'); $ (function() {$ (Fenster) .load (function() { $ ('# foo') show();. }); }); – jimasp

0

würde ich immer Modernizr.js verwenden http://modernizr.com/ dies zu handhaben.

Mit Mondernizr wird eine Klasse 'js' oder 'no-js' zum HTML-Tag Ihrer Seite hinzugefügt.

Von hier aus können Sie Ihre Elemente nur ausblenden, wenn das HTML-Tag die js-Klasse hat.

Modernizr ist groß, für so viele andere Anwendungen und Wert auf das Lesen, wenn Sie habe es nicht vor: http://modernizr.com/docs/

2

Warum nicht nur das ?:

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

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

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

Es scheint gut zu funktionieren !

Grüße.

+4

Das Problem bei diesem Ansatz ist, dass beim erneuten Laden der Seite die ganze Seite flimmert. Es ist am auffälligsten, wenn Sie einen dunklen Hintergrund haben. – meesern

0

Was ich immer mache ist ein leeres Div erstellen. Und wenn einige Daten innerhalb dieser Komponente angezeigt werden müssen, lade ich asynchron Daten (d. H. Html) mit $ .ajax() in sie hinein.

Keine Notwendigkeit für eine zusätzliche Bibliothek.

0

Dies ist mein Vorschlag. Es verwendet this solution zu create eine neue CSS-Regel. Die Hauptsache: Eine CSS-Klasse, die etwas HTML versteckt, wird erstellt, wenn JS verfügbar ist, andernfalls nicht. Und das passiert vor der Hauptinhalt (mit den HTML-Teilen, die zunächst versteckt werden sollten) wird verarbeitet!

<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> 

Ein bisschen komplizierter, aber ich denke, das ist eine richtige Lösung. Der Vorteil ist, dass Flimmern verhindert wird und dass es funktioniert, wenn JS nicht aktiviert ist. Und es erfordert keine jQuery.

0

Nach einiger Zeit des Denkens habe ich die Idee zu der folgenden Lösung.Im Vergleich zu meinem other solution Ich habe es auf das Wesentliche reduziert (und verwendet this eine Klasse von JS hinzugefügt werden):

<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> 

Das script-Tag wird sofort ausgeführt und fügt eine Klasse in einen Behälter. Innerhalb dieses Containers gibt es einige verschachtelte Elemente, die jetzt ausgeblendet werden, weil der Container die spezielle Klasse hat und eine CSS-Regel nun einen Effekt hat.

Wieder geschieht dies, bevor das verbleibende HTML verarbeitet wird (verhindert Blinken). Und auch, wenn JS deaktiviert ist, sind alle Elemente standardmäßig sichtbar - was man Progressive enhancement nennt.

Nicht sicher, ob dies in jedem Browser funktioniert. Aber IMO wäre es eine einfache und saubere Lösung.