消除未样式化内容的闪烁


79

如何停止网页上未样式化内容(FOUC)的闪烁?


如果我们在网页底部引用了样式表的链接标签,则会多次发生这种情况。
RBT

Answers:


3

为避免FOUC,我要做的是:

  • 将主体部分设置为: <body style="visibility: hidden;" onload="js_Load()">

  • 编写一个js_Load()JavaScript函数:document.body.style.visibility='visible';

通过这种方法,网页的正文将保持隐藏状态,直到加载整个页面和CSS文件为止。加载完所有内容后,onload事件将使主体可见。因此,Web浏览器将保持为空,直到所有内容都在屏幕上弹出为止。

这是一个简单的解决方案,但到目前为止,它仍然有效。


60
如果查看器未启用JavaScript,则效果不好,因为这样一来,他们将看不到任何东西。
Stefan

19
-1,用于为未启用javascript的用户,不支持javascript的屏幕阅读器或位于阻止javascript的公司防火墙后面的用户提供建议的解决方案。谷歌搜索“消除不需要的内容的闪光”将显示出许多没有此缺陷的方法。例如,斯蒂芬的答案(一年后)要安全得多。
制造商史蒂夫(Steve)2014年

15
您确实应该<noscript><style>body { visibility: visible; }</style></noscript>在末尾添加,以便该站点也可以在禁用JS的情况下工作。
tomasz86 '16

4
公司防火墙阻止Javascript?变更公司的原因...
unwichtich

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'))方法的* outside *。


4
对我来说,似乎更清洁来代替$('html').show()'$('html').removeClass('hidden');。这样可以更清楚地知道ready函数正在撤消addClass
制造商史蒂夫(Steve)2014年

6
更新:刚刚测试了这种方法。当前版本的jQuery需要使用removeClass(如我所建议的)而不是show(如原始答案中的)来完成-否则html将永远不会显示。我相信jQuery的show()现在可以显式查找并恢复css样式中的任何显示状态,以避免干扰样式。因此,有必要实际删除“隐藏”类。
制造商史蒂夫(Steve)2014年

1
完美运作。选择了removeClass选项,而不是show()
FurryWombat 2015年

3
那么您在<style>html { display: none; }</style>中的<head>,然后是您之前的实际样式的纯CSS解决方案</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>。我确实将其视为不利因素,因为它违反了常规做法。如果有一个deferfor属性,<link>就像for一样,那将是很好的<script>,因为那将使我们能够将其放入<head>并且仍然实现我们的目标。


5
知道这display: none也将隐藏背景图像或颜色很有用。由于我的网站主题是深色的,因此会闪烁白色。visibility: hidden对于我来说,使用效果更好。
KamilDev

1
即使对样式表的引用位于<head>而不是中,该解决方案也将起作用<body>。(尽管我想如果您的页面很长,浏览器可能会在页面末尾加载之前开始显示该页面。但是,这实际上是我的首选行为,因为我的站点正在从数据库中加载大表。)赞成不需要JavaScript的简单解决方案!
马特

26

这是对我有用的,不需要javascript,它非常适合包含许多元素和大量CSS的页面:

首先,增加一个专门<STYLE>设置的<HTML>,在你的HTML,如顶部,能见度“隐藏”和不透明度为“0”的标签,在年初<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;}headhtml{display:block;}样式表中使用基于Chromium的浏览器完全征服FOUC。(我没有遇到过深色背景问题body。)
dotism

一年多以前,该解决方案与Adam Zerner的解决方案之间几乎没有区别。
Stefan

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>

上面提到的代码对我不起作用,这是我的版本:try {var html = document.getElementsByTagName(“ html”)[0]; document.addEventListener(“ DOMContentLoaded”,function(event){html.className ='';}); html.className ='fouc'; } catch(err){}
Manfred Wuits

我喜欢这种方法,但建议使用 classListAPI。
只是一名学生,

2
实际上,为什么首先要使用单独的CSS?为什么不这样做elm.style.display = 'none';,然后取消elm.style.removeProperty('display');呢?
只是一个学生

@Justastudent:因为如果禁用了Javascript,那将显示空白页面。
劳伦斯·多尔

1
@Justastudent:谢谢。我尝试过,并且至少在当前的浏览器中有效。答案扩大。
劳伦斯·多尔 Lawrence Dol)

11

在Firefox Quantum中也可以使用的另一种快速修复方法是中的空<script>标签<head>。但是,这会损害您的Pagespeed洞察力和整体加载时间。

我有100%的成功。我认为这也是为什么上述解决方案可以与其他JS一起工作的主要原因。

<script type="text/javascript">

</script>

1
即使完全不可靠也超级有趣
小家伙

4

没有人谈论CSS @import

那是我的问题,我直接在我的css文件中加载了两个额外的样式表 @import

简单的解决方案:将所有@import链接替换为<link />


这发生在我身上。希望将来@import会同步。
D. Pardal

1

我想出了一种方法,不需要任何真正的代码更改,呜呼!我的问题与在一些javascript文件之后导入多个css文件有关。

为了解决这个问题,我刚刚移动了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)19-10-17

0

到目前为止,我发现的最佳解决方案是这样的:

  1. 将标头的所有样式添加到中的<style/>标签中<head/>

  2. 在样式标签的顶部添加.not-visible-first{visibility: hidden}+其他标题样式

  3. 在主体末尾通过JS添加CSS

    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>

Java脚本

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


请注意,这fadeIn()是一种jQuery方法,而不是本机JavaScript。
BadHorsie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.