我有一个问题在angular.js的指令/类ng-斗篷或ng-show。

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

例子:

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

当前回答

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

只需要把身体里的所有东西都放在一个单独的文件里,然后:

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

这样你就不会看到任何闪烁,因为Angular会在将模板添加到DOM之前对其进行编译。

其他回答

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

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

这个问题的解决方法是确保AngularJS加载在头文件中。参见ngCloak文档:

为了得到最好的结果,angular.js脚本必须加载在头文件中 HTML文件的部分;或者,CSS规则(上面)必须是 包含在应用程序的外部样式表中。

问题2:ng-cloak被过早移除

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

jQuery的解决方案包括在元素中添加style="display:none",只要样式被删除得足够晚,就可以解决这个问题(实际上这些解决方案解决了两个问题)。但是,如果你不喜欢直接在HTML中添加样式,你可以使用ng-show来达到同样的效果。

从问题中的例子开始:

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

在元素中添加额外的ng-show规则:

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

(为了避免问题1,你需要带上斗篷)。

然后在你的app.run set isPageFullyLoaded:

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

注意,根据你正在做的事情,app.run可能是设置isPageFullyLoaded的最佳位置,也可能不是。重要的是确保isPageFullyLoaded在你不想闪烁的东西准备好显示给用户后被设置为true。

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

重要提示:请确保在ng-cloak应用太晚和移除太快的情况下使用解决方案。仅解决其中一个问题可能无法缓解症状。

ngBind和ngBindTemplate是不需要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>

我在指令中使用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的昂贵操作。这样做的代价是使用两个作用域变量来实现相同的目的,而不是一个,但到目前为止,这绝对是最好的选择。

保持下面的声明在头标签固定了这个问题

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

官方文档

由以上讨论可知

[ng-cloak] {
                display: none;
            }

是解决这个问题的完美方法。