Виключіть спалах нестильового вмісту


81

Як зупинити спалах нестильового вмісту (FOUC) на веб-сторінці?


Це трапляється багато разів, якщо ми маємо тег посилань на таблиці стилів, зазначений внизу веб-сторінки.
RBT

Відповіді:


3

Що я зробив, щоб уникнути FOUC:

  • Встановіть секцію тіла як: <body style="visibility: hidden;" onload="js_Load()">

  • Напишіть функцію js_Load()JavaScript:document.body.style.visibility='visible';

При такому підході тіло моєї веб-сторінки залишається прихованим, поки не завантажуються повна сторінка та файли CSS. Як тільки все завантажується, подія onload робить тіло видимим. Отже, веб-браузер залишається порожнім до тих пір, поки на екрані не з’явиться все.

Це просте рішення, але поки воно працює.


60
Непогано, якщо у глядача не ввімкнено javascript, оскільки тоді він нічого не побачить.
Стефан

19
-1 за пропозицію рішення, яке НІЧОГО не покаже для користувачів, які не ввімкнули javascript, або перебувають у програмі зчитування з екрана, яка не підтримує javascript, або які стоять за корпоративним брандмауером, який блокує javascript. Гугл "усунення спалаху небажаного вмісту" покаже численні підходи, у яких немає цієї вади. Наприклад, відповідь Стефана (через рік) набагато безпечніша.
ToolmakerSteve

16
Ви дійсно повинні додати <noscript><style>body { visibility: visible; }</style></noscript>в кінці, щоб сайт також працював із вимкненою JS.
tomasz86

4
Корпоративні брандмауери, що блокують Javascript? Причина зміни компанії ...
Unichtich

3
Відповідь нижче від Джеффа - це правильна відповідь, на мій погляд. Він не покладається на javascript і є більш доступним.
braindigitalis

83

Проблема використання стилю css для спочатку приховування деяких елементів сторінки, а потім використання javascript для зміни стилю на видимий після завантаження сторінки полягає в тому, що люди, у яких не ввімкнено javascript, ніколи не побачать ці елементи. Отже, це рішення, яке не погіршується витончено.

Тому кращим способом є використання javascript як для початкового приховування, так і для повторного відображення цих елементів після завантаження сторінки. Використовуючи jQuery, ми можемо спокуситися зробити щось подібне:

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

Однак, якщо ваша сторінка дуже велика з великою кількістю елементів, тоді цей код не буде застосовано досить скоро (тіло документа не буде готовим досить скоро), і ви все одно можете побачити FOUC. Однак є один елемент, який ми МОЖЕМО приховати, як тільки скрипт зустрінеться в голові, ще до того, як документ буде готовий: тег HTML. Тож ми могли б зробити щось подібне:

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

Зверніть увагу, що метод jQuery addClass () викликається * поза * методу .ready () (або краще .on ('load')).


4
Мені здається чистішим замінити $('html').show()'на $('html').removeClass('hidden');. Це робить зрозумілішим, що функція готовості скасовує addClass.
ToolmakerSteve

6
ОНОВЛЕННЯ: Щойно перевірив цей підхід. Поточна версія jQuery ПОТРІБУЄ, щоб це було зроблено з використанням removeClass(як я пропоную), а не show(як у оригінальній відповіді) - інакше html НІКОЛИ не відображатиметься. Я вважаю, що jQuery's show () тепер явно шукає та відновлює будь-який стан відображення у стилі css, щоб уникнути втручання у стиль. Тому необхідно фактично видалити клас "прихований".
ToolmakerSteve

1
Працює ідеально. Вибрав варіант removeClass, а не show ()
FurryWombat

3
Як щодо CSS тільки рішення , де у вас є <style>html { display: none; }</style>в <head>, і тоді ваші реальні стилі прямо перед </body>?
Адам Цернер

2
Чи не слід шукати подію завантаження замість готової? Після завантаження ми знаємо, що CSS буде готовий. З готовим, ми не знаємо, CSS буде готовим.
Адам Цернер

31

Рішення лише для CSS:

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

Коли браузер аналізує файл HTML:

  • Перше, що він зробить, це приховати <html>.
  • Останнє, що він зробить, це завантажити стилі, а потім відобразити весь вміст із застосованим стилем.

Перевага в порівнянні з рішенням, яке використовує JavaScript, полягає в тому, що воно буде працювати для користувачів, навіть якщо у них відключений JavaScript.

Примітка: вам дозволено класти <link>всередину <body>. Однак я бачу це як мінус, оскільки це порушує загальну практику. Було б непогано, якби існував deferатрибут для такого, <link>як є <script>, тому що це дозволило б нам помістити його в <head>і все-таки досягти своєї мети.


5
Корисно знати, що display: noneтакож приховає фонове зображення або колір. Оскільки мій веб-сайт має темну тему, він буде блимати білим кольором. Використання visibility: hiddenбуло кращим для мого випадку.
KamilDev

1
Це рішення буде працювати, навіть якщо посилання на таблицю стилів знаходиться <head>замість <body>. (Хоча, я гадаю, якщо у вас дійсно довга сторінка, браузер може почати відображати сторінку до того, як був завантажений кінець сторінки. Однак це насправді моя переважна поведінка, оскільки мій сайт завантажує великі таблиці з бази даних). Подобається просте рішення, яке не потребує JavaScript!
Метт

28

Це той, який працював у мене і не вимагає javascript, і він чудово працює для сторінок з багатьма елементами та великою кількістю css:

Спочатку додайте спеціальне <STYLE>налаштування для <HTML>тегу з видимістю «прихований» та прозорістю як «0» у верхній частині вашого HTML, наприклад, на початку <HEAD>елемента, наприклад, у верхній частині вашого HTML додайте :

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

Потім, наприкінці останнього файлу таблиці стилів .css , встановіть стилі видимості та непрозорості на 'visible' та '1' відповідно:

html {
    visibility: visible;
    opacity: 1;
}

Якщо у вас вже є блок стилів для тегу 'html', перемістіть весь стиль 'html' в кінець останнього файлу .css та додайте теги 'visibility' та 'opacity', як описано вище.

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


6
Це справді має бути прийнятою правильною відповіддю. Не відображати жодну сторінку, якщо JS вимкнено або якщо помилка JS є поганою ідеєю, і це набагато доступніше.
braindigitalis

@Jeff, велике спасибі за це рішення! Вирішив мою проблему!
yathrakaaran

1
Це також не заважає браузерам, у яких вимкнено CSS (наприклад, ті, що мають низькошвидкісний доступ до Інтернету або мають обмеження, можуть вимкнути зображення, Javascript та CSS). Opera була, мабуть, найвідомішим прикладом браузера, який колись мав кнопку на головній панелі інструментів для вимкнення CSS. Недоліком цього підходу є те, що якщо файл CSS не вдається завантажити, сторінка буде порожньою. Наприклад, присвоєння файлу CSS "ads.css" спричинить плагіни блокування реклами, і файл не вдасться завантажити, таким чином, сторінка залишиться абсолютно порожньою. (Звичайно, це може бути навмисно ...)
CubicleSoft

Це техніка, яку я використовую і мені найбільше подобається; однак, я вважаю, що мені потрібно використовувати html{display:none;}в таблиці стилів headі html{display:block;}в таблиці стилів, щоб повністю завоювати FOUC за допомогою браузерів на основі Chromium. (Я не відчував проблем із темним фоном, встановленим на body.)
дотизм

Більше року тому між цим рішенням та рішенням Адама Цернера практично немає різниці.
Стефан

17

Рішення, яке не залежить від jQuery, який працюватиме у всіх поточних браузерах і нічого не робитиме у старих браузерах, включає в тег head:

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

Завдяки @justastudent я спробував просто налаштувати, elm.style.display="none";і, здається, він працює за бажанням, принаймні в поточному Firefox Quantum. Отже, тут є більш компактне рішення, яке, на сьогоднішній день, є найпростішим, що я знайшов, що працює.

<script type="text/javascript">
    var elm=document.getElementsByTagName("html")[0];
    elm.style.display="none";
    document.addEventListener("DOMContentLoaded",function(event) { elm.style.display="block"; });
</script>

згаданий код у мене не працював, ось моя версія: спробуйте {var html = document.getElementsByTagName ("html") [0]; document.addEventListener ("DOMContentLoaded", функція (подія) {html.className = '';}); html.className = 'fouc'; } catch (
помилка

Мені подобається такий підхід, але я хотів би запропонувати використання classListAPI.
Просто студент

2
Насправді, навіщо взагалі використовувати окремий CSS? Чому б не зробити, elm.style.display = 'none';а потім скасувати це за допомогою elm.style.removeProperty('display');?
Просто студент

@Justastudent: Тому що це відображатиме порожню сторінку, якщо Javascript вимкнено.
Лоуренс Дол

1
@Justastudent: Дякую. Я спробував це, і це працює, принаймні в поточних браузерах. Відповідь доповнена.
Лоуренс Дол,

11

Іншим швидким виправленням, яке також працює у Firefox Quantum, є порожній <script>тег у<head> . Однак це карає ваші статистичні дані про швидкість сторінки та загальний час завантаження.

У мене був 100% успіх з цим. Я думаю, що це також головна причина, чому описані вище рішення з іншими JS у роботах.

<script type="text/javascript">

</script>

1
Супер цікаво, навіть якщо абсолютно ненадійно
маленький крихітний чоловічок

4

Ніхто не говорив про CSS @import

Це була проблема для мене, я завантажував дві додаткові таблиці стилів безпосередньо у свій CSS-файл @import

Просте рішення: Замініть усі @importпосилання на<link />


Це сталося зі мною. Сподіваюсь, у майбутньому @importбуде синхронно.
Д.Пардал,

1

Я придумав спосіб, який не вимагає жодної реальної зміни коду, вуху! Моя проблема пов’язана з імпортом декількох файлів CSS ПІСЛЯ деяких файлів JavaScript.

Щоб вирішити проблему, я просто перемістив посилання CSS так, щоб вони знаходились вище мого імпорту JavaScript. Це дозволило імпортувати і готувати до роботи якнайшвидше весь мій CSS, так що коли HTML з’являється на екрані, навіть якщо JS не готовий, сторінка буде правильно відформатована


1

Ось мій код .. сподіваюся, він вирішить вашу проблему

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

<script>
    $(document).ready(function() {
        $("body").css('opacity', 1);
    });
</script>

Дивно, але серед десятків фрагментів, які не працюють, щоб зупинити FOUC - цей насправді працює - для мене. Зверніть увагу, що на стилі кузова відсутній кінець, повинен бути<body style="opacity:0;">
abulka

0

Найкраще рішення, яке я знайшов дотепер, таке:

  1. Додайте всі стилі заголовка до <style/>тегу в<head/>

  2. у верхній частині тегу стилю додати .not-visible-first{visibility: hidden}+ інший стиль заголовка

  3. Додайте css через JS в кінці тексту

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

  4. І не забудьте додати .not-visible-first{visibility: visible}до кінцяmain.min.css

Цей параметр створить кращий досвід для користувачів


0

Ви можете спробувати це з ваніллю

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>


0

Найпростіший спосіб, про який я знаю, - це приховати тег html, а потім внизу вашого файлу javascript зникнути тег html.

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();

Джерело: https://gist.github.com/marchershey/139db0e8fd6f03a83578698409d333ce


1
Зверніть увагу, що fadeIn()це метод jQuery, а не власний JavaScript.
BadHorsie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.