我有一个问题在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>

当前回答

除了其他答案,如果你发现模板代码的闪光仍然发生,这可能是你的脚本在页面的底部,这意味着ng-cloak指令将不会直接工作。您可以将脚本移到头部,也可以创建CSS规则。

文档说:“为了达到最好的效果,angular.js脚本必须加载在html文档的头部部分;或者,上面的CSS规则必须包含在应用程序的外部样式表中。”

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

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

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

其他回答

我会用<div ng-cloak>包裹<ul>

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

问题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应用太晚和移除太快的情况下使用解决方案。仅解决其中一个问题可能无法缓解症状。

除了已接受的答案,如果你正在使用另一种触发ng-cloak的方法…

你也可能希望添加一些额外的特性到你的CSS/LESS:

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

我个人决定使用ng-class属性而不是ng-show。我在这方面取得了很多成功,特别是在默认情况下总是不显示弹出窗口的情况下。

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

“股票期权”>

options-modal类的CSS显示:默认为none。show类包含了display:block CSS。

我不能让这些方法工作,所以我最终做了以下。对于你最初想隐藏的元素:

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

然后在你的控制器中,在顶部或顶部附近添加以下内容:

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

这样,元素最初是隐藏的,只有当控制器代码实际运行时才显示。

您可以根据需要调整位置,也许还可以添加一些逻辑。在我的例子中,如果当前没有登录,我将切换到登录路径,并且不希望我的界面事先闪烁,因此我设置了$scope。样式后的登录检查。