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

Posted

技术标签:

【中文标题】AngularJS 策略来防止类的无样式内容闪现【英文标题】:AngularJS strategy to prevent flash-of-unstyled-content for a class 【发布时间】:2013-04-11 01:54:00 【问题描述】:

我有一个 AngularJS 项目,我想在类名的页面加载期间防止 FOUC。我读过关于 ng-template 的内容,但这似乎只对标签内的内容有用。

<body class=" bodyClass ">

我希望它在页面加载时成为“登录”。有什么策略吗?还是我只需要捏造它并将其加载为“登录”并手动使用 javascript 来调整这个实例的 DOM。

【问题讨论】:

使用 ng-cloak 指令查看这篇文章! deansofer.com/posts/view/14/…。如果你把它放在 body 上,它会隐藏所有页面,直到每个 标签都被解析。 请给出答案。 【参考方案1】:

你要找的是ng-cloak。 你必须像这样添加它:

<body class=" bodyClass " ng-cloak>

这样可以防止不必要的闪烁。Link to docs about this.

编辑: 根据文档,建议将下面的 sn-p 放入您的 CSS 文件中。

"为了获得最佳效果,必须在头部加载angular.js脚本 html文档的部分;或者,上面的 css 规则必须 被包含在应用程序的外部样式表中。”

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak 
    display: none !important;

【讨论】:

这是否会导致 Googlebot 不索引内部内容或惩罚网站伪装? @PrathanThananart 如果您的大部分内容是异步加载的,那么可见与否我认为您不会获得太多索引价值。除非 Google JS 抓取变得更加智能! 尽管使用了这种官方方式,但我确实得到了闪光。有时甚至两次...the solution below (styling first, angular undiding only there&then) 工作更可靠恕我直言... @FrankN,文档已更新,提到将 ng-cloak display none 放入 css。谢谢,将编辑我的答案。【参考方案2】:

您应该使用 ng-class

而不是使用类
<body ng-class=" bodyClass ">

【讨论】:

似乎还需要ng-cloak 【参考方案3】:

您面临的一个问题是,在 AngularJS 加载并开始操作 DOM 之前,浏览器会显示 &lt;body&gt; 元素。其他人对ng-class 的评价是正确的,它会应用正确的类,但您仍然需要在 Angular 准备好之前不显示任何内容。

在以前的 Angular 版本中,您可以这样做:

<body style="display:none" ng-show="true" ng-class="bodyClass">

但在最近的版本中这不起作用,因为 ng-show 通过添加和删除 ng-hide 类(它不如元素属性特定)来实现其可见性

我最近一直在做的是这样的:

<head>
...
    <style> <!-- Or you could include this in an existing style sheet -->
        .ng-cloak 
            display: none !important;
        
    </style>    
</head>
<body class="ng-cloak" ng-cloak ng-class="bodyClass">

这样做意味着&lt;body&gt; 将立即被ng-cloak 类的样式隐藏。当 Angular 启动时,它将处理所有指令,包括 ng-classng-cloak,因此您的 &lt;body&gt; 元素将具有正确的类并可见。

在此处阅读更多信息ng-cloak directive

【讨论】:

你不能直接省略类并做[ng-cloak] display... 吗? @ZachL,我不确定我是否理解这个问题。如果您的意思是“为什么不将 display:none 作为内联样式?”,将 display:none 放在内联样式上的问题是它将具有高优先级并且不会被 ng-cloak 删除或 ng-show/ng-hide。这意味着该元素将保持隐藏状态,除非您编写额外的内容从内联样式中删除 display:none。 嘿@Nicholas,我建议您也许可以省略ng-cloak 类,并使用attribute selector 通过ng-cloak 属性选择元素。我无法用ng-cloak 解决我自己的特定问题(无论如何解决),所以无法确认这是否真的有效。 这样的属性样式似乎是可行的。或者您可以跳过该属性而只使用该类:CSS .ng-cloak display: none !important; 和 HTML &lt;body class="ng-cloak"&gt;stuff&lt;/body&gt; 非常适合我。注意:不一定是身体标签。适用于任何标签,例如:&lt;div class="row ng-cloak" ng-cloak&gt;【参考方案4】:

在纯 CSS 中有一个解决 flash 问题的方法,它是防弹的。为您的应用程序根元素的类添加以下内容。此解决方案按处理顺序工作:所有内容都隐藏在 CSS 中,加载 angular,然后 CSS 显示应用程序根目录。我喜欢使用它,因此如果页面上有其他非角度元素,它们将首先呈现,使页面看起来加载速度更快。

/* in your CSS file in head */
.myApp 
    display:none;


<div class="myApp" ng-app="myApp"></div>

在正文结束之前添加您的脚本引用和一些内联 CSS:

<script language="javascript" type="text/javascript" src="angular.min.js"></script>
<style>
.myApp 
    display:block;

</style>
</body>

【讨论】:

这是我找到的最简单和最好的解决方案。 :) 谢谢你,mbokil!【参考方案5】:

我注意到有时甚至 ng-cloak 似乎也不起作用。也许我做错了什么。

<body ng-cloak class=" bodyClass ">

我还做了一件类似于@mbokil 的小事,你可以默认隐藏元素。通过使用针对具有属性 ng-cloak 的任何元素的属性选择器,您可以使用角度指令。这有几个好处,但主要好处是一旦 angular 触发它会删除此属性,这将触发重绘。

<style>
  [ng-cloak] 
    display:none;
  
</style>

【讨论】:

以上是关于AngularJS 策略来防止类的无样式内容闪现的主要内容,如果未能解决你的问题,请参考以下文章

带有扩展类的 AngularJS 动态样式

使用 Load-link/store-conditional 来防止 ABA 的无锁 C++11 示例?

使用现有策略的 AWS Gateway 中的无服务器白名单 IP

Angularjs Module类的介绍及模块化依赖

AngularJS:防止验证隐藏的表单字段

类的无参方法