消除无样式内容的闪烁

Posted

技术标签:

【中文标题】消除无样式内容的闪烁【英文标题】:Eliminate flash of unstyled content 【发布时间】:2011-03-14 09:19:29 【问题描述】:

如何阻止网页上无样式内容 (FOUC) 的闪烁?

【问题讨论】:

如果我们在网页底部引用了样式表的链接标签,这种情况会发生很多次。 【参考方案1】:

在没有 javascript 的情况下避免出现无样式内容的简单解决方案:

<!DOCTYPE html>
<html>
<head>
    <title>Bla bla</title>
    <link href="..." rel="stylesheet" />
    <link href="..." rel="stylesheet" />
</head>
<body style="opacity: 0">
    <!-- All HTML content here -->
    <script src="..."></script>
    <script src="..."></script>
    <style>
        body 
            opacity: 1 !important;
        
    </style>
</body>
</html>

当解析器到达 body 时,它使用“opacity: 0”淡出。当解析器在解析完其他所有内容后最终到达最底部时,使用页内样式再次淡入正文。 !important 关键字很重要 ;-),因为它覆盖了 body 标记的先前内联样式。

在这种情况下,使用“opacity: 0”淡出比“display:none”更好,因为如果你有通过javascript完成的布局操作,当受影响的元素没有渲染时它们可能不起作用。

这对我有用。

【讨论】:

【参考方案2】:

我所知道的最简单的方法是隐藏 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

【讨论】:

请注意,fadeIn() 是一个 jQuery 方法,而不是原生 JavaScript。【参考方案3】:

你可以用香草试试这个

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>

【讨论】:

【参考方案4】:

这是我的代码..希望它能解决你的问题

set &lt;body style="opacity:0;"&gt;

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

【讨论】:

令人惊讶的是,在许多无法阻止 FOUC 的 sn-ps 中——这个确实有效——对我来说。请注意,正文样式上缺少“结尾”,应为&lt;body style="opacity:0;"&gt;【参考方案5】:

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

    将标题的所有样式添加到&lt;head/&gt; 中的&lt;style/&gt; 标记

    在样式标签顶部添加.not-visible-firstvisibility: hidden + 其他标题样式

    在body末尾通过JS添加css

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

    记得在main.min.css末尾加上.not-visible-firstvisibility: visible

此选项将创造更好的用户体验

【讨论】:

【参考方案6】:

我想出了一种不需要任何实际代码更改的方法,哇哦!我的问题与在一些 javascript 文件之后导入几个 css 文件有关。

为了解决这个问题,我刚刚移动了我的 CSS 链接,以便它们位于我的 javascript 导入之上。这使得我所有的 CSS 都可以被导入并尽快准备好,这样当 HTML 出现在屏幕上时,即使 JS 还没有准备好,页面也会被正确格式化

【讨论】:

【参考方案7】:

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

首先,为&lt;HTML&gt; 标记添加一个专用的&lt;STYLE&gt; 设置,在HTML 顶部,例如&lt;HEAD&gt; 元素的开头,可见性为“隐藏”,不透明度为“0” , 在 HTML 的顶部添加

<!doctype html>
<html>
<head>
    <style>htmlvisibility: hidden;opacity:0;</style>

然后,在最后一个 .css 样式表文件的末尾,将可见性和不透明度样式分别设置为“可见”和“1”:

html 
    visibility: visible;
    opacity: 1;

如果您已经有一个现有的 'html' 标记样式块,则将整个 'html' 样式移动到最后一个 .css 文件的末尾,并如上所述添加 'visibility' 和 'opacity' 标记。

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

【讨论】:

这确实应该是公认的正确答案。如果 JS 被禁用或出现 JS 错误,则不显示任何页面是一个坏主意,这更容易访问。 @Jeff,非常感谢您提供此解决方案!解决了我的问题! 这也不会干扰禁用 CSS 的浏览器(例如,互联网访问速度慢或有残疾的浏览器可能会选择禁用图像、Javascript 和 CSS)。 Opera 可能是最著名的浏览器示例,它曾经在主工具栏上有一个按钮来关闭 CSS。这种方法的缺点是如果 CSS 文件加载失败,页面将是空白的。例如,将您的 CSS 文件命名为“ads.css”将触发广告拦截器插件,并且文件将无法加载,从而使页面完全空白。 (当然,这可能是故意的......) 这是我最喜欢使用的技术;但是,我发现我需要在样式表中的headhtmldisplay:block; 中使用htmldisplay:none;,才能使用基于Chromium 的浏览器完全征服FOUC。 (我在body 上设置的深色背景没有遇到过问题。) 这个解决方案与一年多前 Adam Zerner 的解决方案几乎没有区别。【参考方案8】:

另一个同样适用于 Firefox Quantum 的快速修复是 &lt;head&gt; 中的空 &lt;script&gt; 标签。但是,这会损害您的页面速度洞察力和整体加载时间。

我取得了 100% 的成功。我认为这也是主要原因,为什么上述解决方案与其他 JS 在工作中。

<script type="text/javascript">

</script>

【讨论】:

即使完全不可靠也超级有趣【参考方案9】:

一个不依赖于 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'; 捕捉(错误) 我喜欢这种方法,但建议使用classList API。 其实,为什么一开始就使用单独的 CSS 呢?为什么不做elm.style.display = 'none'; 然后用elm.style.removeProperty('display'); 撤消呢? @Justastudent :因为在禁用 Javascript 的情况下会显示一个空白页面。 @Justastudent:谢谢。我试过了,它至少在当前的浏览器中有效。答案增强。【参考方案10】:

没有人谈论过 CSS @import

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

简单的解决方案:将所有@import链接替换为&lt;link /&gt;

【讨论】:

这发生在我身上。我希望将来@import 会是同步的。【参考方案11】:

纯 CSS 解决方案:

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

当浏览器解析 HTML 文件时:

它首先会隐藏&lt;html&gt;。 它要做的最后一件事是加载样式,然后显示应用了样式的所有内容。

与使用 JavaScript 的解决方案相比,这样做的优势在于,即使用户禁用了 JavaScript,它也能正常工作。

注意:你是allowed 把&lt;link&gt; 放在&lt;body&gt; 里面。不过,我确实认为这是一个缺点,因为它违反了惯例。如果&lt;link&gt; 有一个defer 属性就好了,就像&lt;script&gt; 一样,因为这样我们就可以把它放在&lt;head&gt; 中并且仍然实现我们的目标。

【讨论】:

知道display: none 也将隐藏背景图像或颜色很有用。由于我的网站有一个深色主题,它会闪烁白色。使用visibility: hidden 更适合我的情况。 即使对样式表的引用位于 &lt;head&gt; 而不是 &lt;body&gt; 中,此解决方案也将起作用。 (虽然我想如果你有一个很长的页面,浏览器可能会在页面末尾加载之前开始显示页面。但是,这实际上是我的首选行为,因为我的网站正在从数据库中加载大表)。为不需要 JavaScript 的简单解决方案点赞!【参考方案12】:

使用 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'))方法之外调用的。

【讨论】:

对我来说,将$('html').show()' 替换为$('html').removeClass('hidden'); 似乎更简洁。这更清楚地表明,就绪函数正在撤消addClass 更新:刚刚测试了这种方法。当前版本的 jQuery 要求使用 removeClass (正如我建议的那样)而不是 show (如原始答案中的那样)来完成 - 否则 html 将永远不会显示。我相信 jQuery 的 show() 现在显式地从 css 样式中查找并恢复任何显示状态,以避免干扰样式。因此,有必要实际删除“隐藏”类。 完美运行。选择了 removeClass 选项而不是 show() 纯 CSS 解决方案怎么样,在 &lt;head&gt; 中有 &lt;style&gt;html display: none; &lt;/style&gt;,然后在 &lt;/body&gt; 之前有真正的样式? 我们不应该寻找加载事件而不是准备好吗?通过加载,我们知道 CSS 将准备就绪。准备好后,我们不知道 CSS 会准备好。【参考方案13】:

我为避免 FOUC 所做的事情是:

设置正文部分为:&lt;body style="visibility: hidden;" onload="js_Load()"&gt;

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

使用这种方法,我的网页正文会一直隐藏,直到整个页面和 CSS 文件加载完毕。加载完所有内容后,onload 事件会使主体可见。因此,网络浏览器一直是空的,直到屏幕上弹出所有内容。

这是一个简单的解决方案,但到目前为止它正在工作。

【讨论】:

如果查看者没有启用 javascript,那就不好了,因为那样他们就什么也看不到了。 -1 用于建议一个解决方案,该解决方案将向未启用 javascript 或使用不支持 javascript 的屏幕阅读器或位于阻止的公司防火墙后面的用户显示任何内容javascript。谷歌搜索“消除不需要的内容的闪光”将显示许多不存在此缺陷的方法。例如,Stefan 的答案(一年后)要安全得多。 你真的应该在最后添加&lt;noscript&gt;&lt;style&gt;body visibility: visible; &lt;/style&gt;&lt;/noscript&gt;,这样网站也可以在禁用 JS 的情况下工作。 企业防火墙阻止 Javascript?换公司的理由... 以下来自 Jeff 的答案是我认为的正确答案。它不依赖于 javascript,并且更易于访问。

以上是关于消除无样式内容的闪烁的主要内容,如果未能解决你的问题,请参考以下文章

uniapp input输入内容时内容闪烁问题解决

hw1

FOUC

在R闪亮中,如何在不使用renderUI的情况下首次调用应用程序时消除侧边栏中所有条件面板的闪烁?

课堂学习Scrum站立会议

AngularJS 策略来防止类的无样式内容闪现