231

我在 angular.js 中遇到指令/类ng-cloakng-show.

Chrome 可以正常工作,但 Firefox 会导致带有ng-cloak或的元素闪烁ng-show。恕我直言,这是由转换ng-cloak/ng-show引起的style="display: none;",可能是 Firefox javascript 编译器有点慢,所以元素出现一段时间然后隐藏?

例子:

<ul ng-show="foo != null" ng-cloak>..</ul>
4

29 回答 29

387

display: none;虽然文档没有提到它,但将规则添加到您的 CSS 中可能还不够。如果您在正文中加载 angular.js 或模板没有及时编译,请使用该ng-cloak指令在您的 CSS 中包含以下内容:

/* 
  Allow angular.js to be loaded in body, hiding cloaked elements until 
  templates compile.  The !important is important given that there may be 
  other selectors that are more specific or come later and might alter display.  
 */
[ng\:cloak], [ng-cloak], .ng-cloak {
  display: none !important;
}

正如评论中提到的,这!important很重要。例如,如果您有以下标记

<ul class="nav">
  <li><a href="/foo" ng-cloak>{{bar}}</a></li>
</ul>

并且您碰巧正在使用bootstrap.css,以下选择器更适合您ng-cloak的 'ed 元素

.nav > li > a {
  display: block;
}

因此,如果您包含简单display: none;的规则,Bootstrap 的规则将优先,display并将设置为block,因此您会在模板编译之前看到闪烁。

于 2012-11-07T18:52:00.643 回答
47

文档中所述,您应该在 CSS 中添加一条规则以根据ng-cloak属性隐藏它:

[ng\:cloak], [ng-cloak], .ng-cloak {
    display: none;
}

我们在“Built with Angular”网站上使用了类似的技巧,你可以在 Github 上查看源代码:https ://github.com/angular/builtwith.angularjs.org

希望有帮助!

于 2012-06-29T08:59:34.160 回答
33

确保 AngularJS 包含在headHTML 中。请参阅ngCloak 文档

为获得最佳效果,必须在 html 文件的 head 部分加载 angular.js 脚本;或者,css 规则(如上)必须包含在应用程序的外部样式表中。

于 2013-03-01T20:59:09.837 回答
27

我在使用 ngCloak 时运气不佳。尽管上面提到了一切,我仍然会闪烁。避免轻弹的唯一可靠方法是将您的内容放在模板中并包含该模板。在 SPA 中,在被 Angular 编译之前唯一会被评估的 HTML 是你的主 index.html 页面。

只需将身体内的所有东西都放在一个单独的文件中,然后:

<ng-include src="'views/indexMain.html'"></ng-include>

你不应该以这种方式出现任何闪烁,因为 Angular 会在将模板添加到 DOM 之前对其进行编译。

于 2013-10-10T16:47:20.273 回答
22

ngBindngBindTemplate是不需要 CSS 的替代方案:

<div ng-show="foo != null" ng-cloak>{{name}}</div>  <!-- requires CSS -->
<div ng-show="foo != null" ng-bind="name"></div>
<div ng-show="foo != null" ng-bind-template="name = {{name}}"></div>
于 2012-11-07T20:21:01.137 回答
20

如果您使用另一种触发 ng-cloak 的方法,除了接受的答案...

您可能还希望为您的 CSS/LESS 添加一些额外的特性:

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
.ng-cloak, .x-ng-cloak,
.ng-hide {
    display: none !important;
}
于 2014-01-10T02:00:48.633 回答
15

我有一个类似的问题,发现如果你有一个包含转换的类,元素会闪烁。我尝试添加 ng-cloak 没有成功,但是通过删除转换按钮停止闪烁。

我正在使用离子框架,按钮轮廓有这个过渡

.button-outline {
  -webkit-transition: opacity .1s;
  transition: opacity .1s;
}

只需覆盖类以删除转换,按钮将停止闪烁。

更新

再次在 ionic 上使用 ng-show/ng-hide 时会出现闪烁。添加以下 CSS 可解决此问题:

.ng-hide-add,
.ng-hide-remove {
  display: none !important;
}

资料来源:http: //forum.ionicframework.com/t/beta-14-ng-hide-show/14270/9

于 2015-04-29T12:27:58.353 回答
9

我遇到了一个问题<div ng-show="expression">,在 ng-show 指令有机会运行之前,即使“表达式”最初是错误的,a 最初也会在几分之一秒内可见。

我使用的解决方案是手动添加“ng-hide”类,如<div ng-show="expression" ng-hide>,以确保它最初是隐藏的。之后,ng-show 指令将根据需要添加/删除 ng-hide 类。

于 2015-11-16T19:48:32.017 回答
7

尝试关闭 Firebug。我是认真的。这对我有帮助。

应用接受的答案,然后确保Firefox中的Firebug已关闭:按 F12 然后关闭此页面的 Firebug - 右上角的小按钮。

于 2016-02-26T08:20:38.950 回答
6

实际上有两个不同的问题会导致闪烁问题,您可能会面临其中一个或两个问题。

问题 1:ng-cloak 应用得太晚

此问题已解决,因为此页面上的许多答案中都描述了确保 AngularJS 已加载到头部。请参阅ngCloak 文档

为获得最佳效果,必须在 html 文件的 head 部分加载 angular.js 脚本;或者,css 规则(如上)必须包含在应用程序的外部样式表中。

问题 2:ng-cloak 被移除太快

当您的页面上有大量 CSS 且规则相互层叠并且较深层的 CSS 在应用顶层之前闪现时,最有可能发生此问题。

涉及添加style="display:none"到您的元素的答案中的 jQuery 解决方案确实可以解决此问题,只要足够晚地删除样式(实际上这些解决方案解决了这两个问题)。但是,如果您不想直接向 HTML 添加样式,您可以使用ng-show.

从问题中的示例开始:

<ul ng-show="foo != null" ng-cloak>..</ul>

向您的元素添加额外的 ng-show 规则:

<ul ng-show="isPageFullyLoaded && (foo != null)" ng-cloak>..</ul>

(您需要保留ng-cloak以避免问题1)。

然后在你的 app.run 集中isPageFullyLoaded

app.run(['$rootScope', function ($rootScope) {
    $rootScope.$safeApply = function (fn) {
        $rootScope.isPageFullyLoaded = true;
    }
}]);

请注意,根据您的具体操作, app.run 可能是也可能不是设置的最佳位置isPageFullyLoaded。重要的是确保isPageFullyLoaded在您不想闪烁的任何内容准备好向用户显示之后设置为 true。

听起来问题 1是 OP 遇到的问题,但其他人发现解决方案不起作用或仅部分起作用,因为他们正在解决问题 2或同时解决问题。

重要提示:请务必将解决方案应用于 ng-cloak 应用得太晚和很快被删除。仅解决其中一个问题可能无法缓解症状。

于 2017-03-01T09:17:40.340 回答
4

我们在公司遇到了这个问题,并通过在那些闪烁的 ng-show 元素的 CSS 样式中添加“display: none”来解决它。我们根本不需要使用 ng-cloak。与此线程中的其他人不同,我们在 Safari 中遇到了这个问题,但在 Firefox 或 Chrome 中没有遇到这个问题——可能是由于Safari 在 iOS7 中的延迟重绘错误

于 2013-11-14T01:33:53.403 回答
3

对于它的价值,我有一个类似的问题 ng-cloak 不起作用。可能值得检查您的应用程序/站点启用缓存以重用源文件,看看是否有帮助。

随着我的闪烁磨合,我在 DevTools 打开并禁用缓存的情况下进行测试。在启用缓存的情况下关闭面板解决了我的问题。

于 2014-02-27T21:53:19.160 回答
3

将以下语句保留在 head 标签中可解决此问题

<style type="text/css">
    [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
    display: none !important;
}
</style>

官方文档

于 2015-07-19T12:27:04.603 回答
3

我无法让这些方法中的任何一个起作用,所以我最终做了以下事情。对于您最初想要隐藏的元素:

<div <!--...--> style="display: none;" ng-style="style">

然后在您的控制器中,将其添加到顶部或顶部附近:

$scope.style = { display: 'block' };

这样,该元素最初是隐藏的,仅在控制器代码实际运行时显示。

您可以根据需要调整展示位置,或许可以添加一些逻辑。就我而言,如果当前没有登录,我会切换到登录路径,并且不希望我的界面事先闪烁,所以我$scope.style在登录检查之后设置。

于 2016-07-06T04:28:42.760 回答
2

最好使用ng-if而不是ng-show. ng-if 完全删除并重新创建 DOM 中的元素,并有助于避免 ng-shows 闪烁。

于 2016-02-10T09:32:45.060 回答
2

我正在使用 ionic 框架,在某些情况下添加 css 样式可能不起作用,您可以尝试使用 ng-if 代替 ng-show / ng-hide

参考:https://books.google.com.my/books?id=-_5_CwAAQBAJ&pg=PA138&lpg=PA138&dq=ng-show+hide+flickering+in+ios&source=bl&ots=m2Turk8DFh&sig=8hNiWx26euGR2k_WeyaVzdixJ8k&hl=en&sa=X&redir_esc=y#v =onepage&q=ng-show%20hide%20flickering%20in%20ios&f=false

于 2016-03-21T06:31:31.903 回答
2

您最好参考 Angular 文档,因为版本 [1.4.9] 已更新到以下,使其可以支持 data-ng-cloak 指令。

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
  display: none !important;
}
于 2016-03-25T11:07:13.470 回答
2

我尝试了上面的 ng-cloak 解决方案,但 Firefox 仍然存在间歇性问题。对我有用的唯一解决方法是延迟表单的加载,直到 Angular 完全加载。

我只是在应用程序中添加了 ng-init 并在表单端使用 ng-if 来检查我设置的变量是否已经加载。

<div ng-app="myApp" ng-init="loaded='yes'"> 
   <form ng-if="loaded.length > 0">
      <!--all my elements here-->
   </form>
</div>
于 2016-08-04T20:16:02.667 回答
1

除了其他答案之外,如果您发现模板代码的闪烁仍然存在,则很可能您的脚本位于页面底部,这意味着直接向上的 ng-cloak 指令将不起作用。您可以将脚本移动到头部或创建 CSS 规则。

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

现在,它不必是外部样式表,而只是在头部的一个元素中。

<style type="text/css">
  .ng-cloak {
    display: none !important;
  }
</style>

来源:https ://docs.angularjs.org/api/ng/directive/ngCloak

于 2015-03-25T11:54:46.150 回答
1

我尝试了此处发布的所有解决方案,但仍然在 Firefox 中闪烁。

如果它对任何人有帮助,我通过添加到主要内容 div 来解决它,然后在从服务器获取数据后加载所有style="display: none;"内容后使用 jQuery(我已经在页面上使用它) ;$('#main-div-id').show();

于 2015-12-10T15:35:10.583 回答
1

实际上,我发现Rick Strahl 的 Web Log中的建议完美地解决了我的问题(因为我仍然遇到 ng-cloak 有时会闪烁原始 {{code}} 的奇怪问题,尤其是在运行 Firebug 时):

核选项:手动隐藏内容

使用显式 CSS 是最好的选择,因此不需要以下内容。但我会在这里提到它,因为它提供了一些见解,您可以在加载其他框架或您自己的基于标记的模板中手动隐藏/显示内容。

在我发现我可以将 CSS 样式显式嵌入到页面中之前,我试图弄清楚为什么 ng-cloak 没有完成它的工作。在浪费了一个小时无处可去之后,我终于决定手动隐藏和显示容器。这个想法很简单——最初隐藏容器,然后在 Angular 完成初始处理并从页面中删除模板标记后显示它。

您可以手动隐藏内容并在 Angular 获得控制后使其可见。为此,我使用了:

<div id="mainContainer" class="mainContainer boxshadow"
    ng-app="app" style="display:none">

注意 display: none 样式,它最初在页面上显式隐藏元素。

然后,一旦 Angular 运行了它的初始化并有效地处理了页面上的模板标记,您就可以显示内容。对于 Angular,这个“就绪”事件是 app.run() 函数:

app.run( function ($rootScope, $location, cellService) {        
    $("#mainContainer").show();
    …
});

这有效地删除了 display:none 样式和内容显示。当 app.run() 触发时,DOM 已经准备好显示填充数据或至少是空数据——Angular 已经获得了控制权。

于 2016-02-02T05:49:05.570 回答
1

我尝试了上面所有的答案,但没有任何效果。使用 ionic 开发混合应用程序并试图使错误消息不闪烁。 我最终通过向我的元素添加一个 ng-hide 类来解决我的问题。 我的 div 已经有 ng-show 以在出现错误时显示元素。添加 ng-hide 将 div 设置为在加载 angular 之前不显示。不需要 ng-cloak 或在头部添加角度。

于 2016-06-18T20:29:01.367 回答
1

AS 从上面的讨论

[ng-cloak] {
                display: none;
            }

是解决问题的完美方法。

于 2016-06-23T06:54:20.360 回答
1

我在指令中使用 ng-show 来显示和隐藏弹出窗口。

<div class="..." ng-show="showPopup">

以上都不适合我,使用 ng-if 代替 ng-show 将是一种矫枉过正。这意味着每次单击时都会将整个弹出内容删除并添加到 DOM 中。相反,我在同一个元素中添加了一个 ng-if,以确保它不会在文档加载时显示:

<div class="..." ng-show="showPopup" ng-if="popupReady">

之后,我将初始化添加到负责该指令的控制器中,并带有超时:

$timeout(function () {
    $scope.popupReady = true;
});

通过这种方式,我消除了闪烁问题,并避免了每次单击时昂贵的 DOM 插入操作。这是以使用两个范围变量而不是一个目的为代价的,但到目前为止,这绝对是最好的选择。

于 2016-08-08T09:06:00.650 回答
1

试过ng-cloak但仍然短暂眨眼。下面的代码完全摆脱了它们。

<body style="display:none;" ng-style="{'display':'block'}">
于 2018-04-03T09:16:03.300 回答
1

上面列出的解决方案都不适合我。然后我决定查看实际的函数,并意识到当“$scope.watch”被触发时,它在 name 字段中输入了一个值,而这并非如此。所以在我设置的代码中,oldValue 和 newValue 然后

$scope.$watch('model.value', function(newValue, oldValue) {
if (newValue !== oldValue) {
validateValue(newValue);
}
});

本质上,当在这种情况下触发 scope.watch 时,AngularJS 会监视名称变量(model.value)的更改

于 2018-07-16T10:31:09.920 回答
0

我会<ul>用一个<div ng-cloak>

于 2012-06-28T21:58:57.387 回答
0

我个人决定使用ng-class属性而不是ng-show. 我在这条路线上取得了更大的成功,特别是对于默认情况下始终不显示的弹出窗口。

曾经是什么<div class="options-modal" ng-show="showOptions"></div>

就是现在:<div class="options-modal" ng-class="{'show': isPrintModalShown}">

display: none默认情况下,options-modal 类的 CSS 。show 类包含display:blockCSS。

于 2017-11-01T04:54:23.577 回答
-2

避免换行

<meta http-equiv="Content-Security-Policy"              content="
default-src 'FOO';   
script-src 'FOO';    
style-src  'FOO'; 
font-src 'FOO';">

适用于 Firefox 45.0.1

<meta http-equiv="Content-Security-Policy"              content="    default-src 'FOO';    script-src 'FOO';     style-src  'FOO';    font-src 'FOO';">
于 2016-03-30T20:18:49.767 回答