Beseitigen Sie das Aufblitzen von nicht gestylten Inhalten

79

Wie stoppe ich das Flashen von nicht gestylten Inhalten (FOUC) auf einer Webseite?

CMS-Kritiker
quelle
Dies passiert oft, wenn wir das Link-Tag der Stylesheets unten auf der Webseite haben.
RBT

Antworten:

3

Was ich getan habe, um FOUC zu vermeiden, ist:

  • Stellen Sie den Körperteil wie folgt ein: <body style="visibility: hidden;" onload="js_Load()">

  • Schreiben Sie eine js_Load()JavaScript-Funktion:document.body.style.visibility='visible';

Bei diesem Ansatz bleibt der Hauptteil meiner Webseite verborgen, bis die gesamte Seite und die CSS-Dateien geladen sind. Sobald alles geladen ist, macht das Onload-Ereignis den Körper sichtbar. Der Webbrowser bleibt also leer, bis alles auf dem Bildschirm erscheint.

Es ist eine einfache Lösung, aber bisher funktioniert es.

Álvaro Durán
quelle
60
Nicht gut, wenn für einen Viewer kein Javascript aktiviert ist, da er dann nichts sieht.
Stefan
19
-1, um eine Lösung vorzuschlagen, die NICHTS für Benutzer anzeigt, für die Javascript nicht aktiviert ist oder die sich auf einem Bildschirmleser befinden, der Javascript nicht unterstützt, oder die sich hinter einer Unternehmensfirewall befinden, die Javascript blockiert. Das Googeln "Flash von unerwünschten Inhalten entfernen" zeigt zahlreiche Ansätze, die diesen Fehler nicht aufweisen. Zum Beispiel ist Stefans Antwort (ein Jahr später) viel sicherer.
ToolmakerSteve
15
Sie sollten wirklich <noscript><style>body { visibility: visible; }</style></noscript>am Ende hinzufügen, damit die Site auch mit deaktiviertem JS funktioniert.
Thomasz86
4
Firmenfirewalls blockieren Javascript? Ein Grund, die Firma zu wechseln ...
unwichtich
3
Die Antwort unten von Jeff ist meiner Meinung nach die richtige Antwort. Es basiert nicht auf Javascript und ist leichter zugänglich.
Braindigitalis
83

Das Problem bei der Verwendung eines CSS-Stils zum anfänglichen Ausblenden einiger Seitenelemente und der Verwendung von Javascript, um den Stil nach dem Laden der Seite wieder sichtbar zu machen, besteht darin, dass Personen, für die Javascript nicht aktiviert ist, diese Elemente niemals sehen können. Es ist also eine Lösung, die sich nicht elegant verschlechtert.

Ein besserer Weg ist daher, Javascript zu verwenden, um diese Elemente nach dem Laden der Seite sowohl zunächst auszublenden als auch erneut anzuzeigen. Mit jQuery könnten wir versucht sein, Folgendes zu tun:

$(document).ready(function() {
    $('body').hide();
    $(window).on('load', function() {
        $('body').show();
    });
});

Wenn Ihre Seite jedoch sehr groß ist und viele Elemente enthält, wird dieser Code nicht früh genug angewendet (der Dokumententext wird nicht früh genug fertig sein) und Sie sehen möglicherweise immer noch eine FOUC. Es gibt jedoch ein Element, das wir ausblenden können, sobald ein Skript im Kopf gefunden wird, noch bevor das Dokument fertig ist: das HTML-Tag. Also könnten wir so etwas machen:

<html>
  <head>
  <!-- Other stuff like title and meta tags go here -->
  <style type="text/css">
    .hidden {display:none;}
  </style>
  <script type="text/javascript" src="/scripts/jquery.js"></script>
  <script type="text/javascript">
    $('html').addClass('hidden');
    $(document).ready(function() {    // EDIT: From Adam Zerner's comment below: Rather use load: $(window).on('load', function () {...});
      $('html').show();  // EDIT: Can also use $('html').removeClass('hidden'); 
     });  
   </script>
   </head>
   <body>
   <!-- Body Content -->
   </body>
</html>

Beachten Sie, dass die Methode jQuery addClass () * außerhalb * der Methode .ready () (oder besser .on ('load')) aufgerufen wird.

Stefan
quelle
4
Mir scheint es sauberer zu ersetzen $('html').show()'mit $('html').removeClass('hidden');. Dies macht klarer, dass die Bereitschaftsfunktion das rückgängig macht addClass.
ToolmakerSteve
6
UPDATE: Habe gerade diesen Ansatz getestet. Die aktuelle Version von jQuery ERFORDERT, dass dies removeClass(wie ich vorschlage) und nicht show(wie in der ursprünglichen Antwort) verwendet wird - andernfalls wird das HTML NIEMALS angezeigt . Ich glaube, dass jQuerys show () jetzt explizit nach dem Anzeigezustand des CSS-Stils sucht und diesen wiederherstellt, um eine Beeinträchtigung des Stils zu vermeiden. Daher ist es notwendig, die 'versteckte' Klasse tatsächlich zu entfernen.
ToolmakerSteve
1
Funktioniert perfekt. Ich habe mich für die Option removeClass entschieden und nicht für show ()
FurryWombat
3
Was ist mit einer CSS-Lösung, bei der Sie <style>html { display: none; }</style>die <head>und dann Ihre realen Stile direkt zuvor haben </body>?
Adam Zerner
2
Sollten wir nicht nach dem Ladeereignis suchen, anstatt bereit zu sein? Mit dem Laden wissen wir, dass das CSS bereit sein wird. Mit ready wissen wir nicht, ob das CSS fertig sein wird.
Adam Zerner
31

Eine reine CSS-Lösung:

<html>
  <head>
    <style>
      html {
        display: none;
      }
    </style>
    ...
  </head>
  <body>
    ...
    <link rel="stylesheet" href="app.css"> <!-- should set html { display: block; } -->
  </body>
</html>

Während der Browser die HTML-Datei analysiert:

  • Das erste, was es tun wird, ist sich zu verstecken <html>.
  • Als letztes werden die Stile geladen und dann der gesamte Inhalt mit angewendetem Stil angezeigt.

Dies hat gegenüber einer Lösung, die JavaScript verwendet, den Vorteil, dass sie auch dann für Benutzer funktioniert, wenn JavaScript deaktiviert ist.

Hinweis: Sie erlaubt setzen <link>innerhalb von <body>. Ich sehe es jedoch als Nachteil, weil es gegen die gängige Praxis verstößt. Es wäre schön, wenn es ein deferAttribut für das <link>gibt <script>, was es gibt , denn das würde es uns ermöglichen, es in das zu setzen <head>und trotzdem unser Ziel zu erreichen.

Adam Zerner
quelle
5
Nützlich zu wissen, dass display: noneauch das Hintergrundbild oder die Hintergrundfarbe ausgeblendet wird. Da meine Website ein dunkles Thema hat, würde sie weiß blinken. Verwenden visibility: hiddenwar für meinen Fall besser.
KamilDev
1
Diese Lösung funktioniert auch dann, wenn der Verweis auf das Stylesheet <head>anstelle von steht <body>. (Obwohl ich nehme an, wenn Sie eine wirklich lange Seite hatten, beginnt der Browser möglicherweise damit, die Seite anzuzeigen, bevor das Ende der Seite geladen wurde. Dies ist jedoch mein bevorzugtes Verhalten, da meine Site große Tabellen aus einer Datenbank lädt.) Daumen hoch für eine einfache Lösung, die kein JavaScript erfordert!
Matt
26

Dies ist die, die für mich funktioniert hat und kein Javascript erfordert. Sie funktioniert hervorragend für Seiten mit vielen Elementen und viel CSS:

Fügen Sie zunächst eine dedizierte <STYLE>Einstellung für das <HTML>Tag hinzu, wobei die Sichtbarkeit "ausgeblendet" und die Deckkraft "0" oben in Ihrem HTML-Code sind, z. B. am Anfang des <HEAD>Elements, z. B. oben in Ihrem HTML-Code :

<!doctype html>
<html>
<head>
    <style>html{visibility: hidden;opacity:0;}</style>

Stellen Sie dann am Ende Ihrer letzten CSS-Stylesheet-Datei die Sichtbarkeits- und Deckkraftstile auf "sichtbar" bzw. "1" ein:

html {
    visibility: visible;
    opacity: 1;
}

Wenn Sie bereits einen Stilblock für das 'HTML'-Tag haben, verschieben Sie den gesamten' HTML'-Stil an das Ende der letzten CSS-Datei und fügen Sie die Tags 'Sichtbarkeit' und 'Deckkraft' wie oben beschrieben hinzu.

https://gist.github.com/electrotype/7960ddcc44bc4aea07a35603d1c41cb0

Jeff
quelle
6
Dieser sollte wirklich die akzeptierte richtige Antwort sein. Es ist eine schlechte Idee, keine Seite anzuzeigen, wenn JS deaktiviert ist oder wenn ein JS-Fehler vorliegt, und dies ist viel zugänglicher.
Braindigitalis
@ Jeff, vielen Dank für diese Lösung! Mein Problem gelöst!
Yathrakaaran
1
Dies beeinträchtigt auch nicht Browser mit deaktiviertem CSS (z. B. Benutzer mit langsamem Internetzugang oder Behinderungen können Bilder, Javascript und CSS deaktivieren). Opera war wahrscheinlich das bekannteste Beispiel für einen Browser, der an einer Stelle eine Schaltfläche in der Hauptsymbolleiste hatte, um CSS zu deaktivieren. Der Nachteil dieses Ansatzes ist, dass die Seite leer ist, wenn die CSS-Datei nicht geladen werden kann. Wenn Sie beispielsweise Ihre CSS-Datei "ads.css" nennen, werden Plugins für Werbeblocker ausgelöst, und die Datei kann nicht geladen werden, sodass die Seite vollständig leer bleibt. (Natürlich könnte das beabsichtigt sein ...)
CubicleSoft
Dies ist die Technik, die ich verwende und die mir am besten gefällt. Ich finde jedoch, dass ich html{display:none;}im headund html{display:block;}im Stylesheet verwenden muss, um FOUC mit Chromium-basierten Browsern vollständig zu erobern. (Ich habe keine Probleme mit einem dunklen Hintergrund auf dem body.)
Dotismus
Es gibt praktisch keinen Unterschied zwischen dieser Lösung und der Lösung von Adam Zerner vor mehr als einem Jahr.
Stefan
17

Eine Lösung, die nicht von jQuery abhängt, die auf allen aktuellen Browsern funktioniert und auf alten Browsern nichts bewirkt, enthält Folgendes in Ihrem Head-Tag:

<head>
    ...

    <style type="text/css">
        .fouc-fix { display:none; }
    </style>
    <script type="text/javascript">
        try {
            var elm=document.getElementsByTagName("html")[0];
            var old=elm.class || "";
            elm.class=old+" fouc-fix";
            document.addEventListener("DOMContentLoaded",function(event) {
                elm.class=old;
                });
            }
        catch(thr) {
            }
    </script>
</head>

Dank @justastudent habe ich versucht, nur Einstellungen vorzunehmen, elm.style.display="none";und es scheint wie gewünscht zu funktionieren, zumindest im aktuellen Firefox Quantum. Hier ist also eine kompaktere Lösung, die bisher die einfachste ist, die ich gefunden habe und die funktioniert.

<script type="text/javascript">
    var elm=document.getElementsByTagName("html")[0];
    elm.style.display="none";
    document.addEventListener("DOMContentLoaded",function(event) { elm.style.display="block"; });
</script>
Lawrence Dol
quelle
Der erwähnte Code hat bei mir nicht funktioniert. Hier ist meine Version: try {var html = document.getElementsByTagName ("html") [0]; document.addEventListener ("DOMContentLoaded", Funktion (Ereignis) {html.className = '';}); html.className = 'fouc'; } catch (err) {}
Manfred Wuits
Ich mag diesen Ansatz, möchte aber die Verwendung der classListAPI vorschlagen .
Nur ein Student
2
Warum sollte man überhaupt das separate CSS verwenden? Warum nicht tun elm.style.display = 'none';und das dann rückgängig machen elm.style.removeProperty('display');?
Nur ein Student
@Justastudent: Da dies eine leere Seite anzeigen würde, falls Javascript deaktiviert ist.
Lawrence Dol
1
@ Justastudent: Danke. Ich habe das versucht und es funktioniert zumindest in aktuellen Browsern. Antwort erweitert.
Lawrence Dol
11

Eine andere schnelle Lösung, die auch in Firefox Quantum funktioniert, ist ein leeres <script>Tag in der <head>. Dies beeinträchtigt jedoch Ihre Einblicke in die Seitengeschwindigkeit und die Gesamtladezeit.

Ich hatte 100% Erfolg damit. Ich denke, es ist auch der Hauptgrund, warum oben Lösungen mit anderen JS in Arbeit sind.

<script type="text/javascript">

</script>
Paul Cream
quelle
1
Super interessant, auch wenn es völlig unzuverlässig ist
kleiner kleiner Mann
4

Niemand hat über CSS gesprochen @import

Das war das Problem für mich, mit dem ich zwei zusätzliche Stylesheets direkt in meine CSS-Datei geladen habe @import

Einfache Lösung: Ersetzen Sie alle @importLinks durch<link />

danidee
quelle
Das ist mir passiert. Ich hoffe in Zukunft @importwird synchron sein.
D. Pardal
1

Ich habe einen Weg gefunden, der keinerlei echte Codeänderung erfordert, woohoo! Mein Problem hing mit dem Importieren mehrerer CSS-Dateien NACH einigen Javascript-Dateien zusammen.

Um das Problem zu beheben, habe ich meine CSS-Links so verschoben, dass sie über meinen Javascript-Importen liegen. Auf diese Weise konnte mein gesamtes CSS importiert und so schnell wie möglich gestartet werden. Wenn der HTML-Code auf dem Bildschirm angezeigt wird, wird die Seite ordnungsgemäß formatiert, auch wenn der JS nicht bereit ist

Jake Boomgaarden
quelle
1

Hier ist mein Code. Ich hoffe, er löst Ihr Problem

set <body style="opacity:0;">

<script>
    $(document).ready(function() {
        $("body").css('opacity', 1);
    });
</script>
Coding_snakeZ
quelle
Erstaunlicherweise unter Dutzenden von Schnipsel, die nicht funktionieren, um FOUC zu stoppen - dieser funktioniert tatsächlich - für mich. Beachten Sie, dass es ein fehlendes Ende gibt "auf dem Körperstil, sollte sein<body style="opacity:0;">
abulka
0

Die beste Lösung, die ich bisher gefunden habe, ist folgende:

  1. Fügen Sie einem <style/>Tag in alle Stile Ihres Headers hinzu<head/>

  2. Fügen Sie oben im Stil-Tag .not-visible-first{visibility: hidden}+ anderen Header-Stil hinzu

  3. Fügen Sie CSS über JS am Ende des Körpers hinzu

    document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeend","<link rel=\"stylesheet\" href=\"/css/main.min.css?v=1.2.4338\" />");

  4. Und denken Sie daran .not-visible-first{visibility: visible}, am Ende von hinzuzufügenmain.min.css

Diese Option sorgt für eine bessere Benutzererfahrung

Nagibaba
quelle
0

Sie könnten dies mit Vanille versuchen

function js_method(){
//todos
var elementDiv = document.getElementById("main");
elementDiv.style.display ="block";
}
<body onload="js_method()" id="main" style="display:none">
//todos
<h2>Hello</h2>
</body>

Nazehs
quelle
0

Der einfachste Weg, den ich kenne, besteht darin, das HTML-Tag auszublenden und dann am Ende Ihrer Javascript-Datei das HTML-Tag einzublenden.

HTML

<html style="display:none;">
    ...
</html>

Javascript

/*
 * FOUC Fix - Flash of Unstyled Content
 * By default, the <html> tag is hidden to prevent the flash of unstyled content.
 * This simple fadeIn() function will allow the page to gracefully fade in once 
 * all assets are loaded. This line of code must remain at the bottom of the js 
 * assets.
 */

$( 'html' ).fadeIn();

Quelle: https://gist.github.com/marchershey/139db0e8fd6f03a83578698409d333ce

Marc
quelle
Beachten Sie, dass dies fadeIn()eine jQuery-Methode ist, kein natives JavaScript.
BadHorsie