我有一个问题在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>
我有一个问题在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>
当前回答
试着关闭Firebug。我是认真的。这对我很有帮助。
应用已接受的答案,然后确保Firefox中的Firebug已关闭:按F12,然后关闭此页的Firebug -右上角的小按钮。
其他回答
实际上,我发现Rick Strahl's 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来说,这个' ready '事件就是app.run()函数:
app.run( function ($rootScope, $location, cellService) {
$("#mainContainer").show();
…
});
这有效地删除了display:none样式和内容显示。当app.run()触发时,DOM已经准备好显示已填充的数据,或者至少是空数据——Angular已经获得了控制权。
你最好参考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;
}
实际上有两个独立的问题会导致闪烁问题,你可能会面临其中一个或两个。
问题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应用太晚和移除太快的情况下使用解决方案。仅解决其中一个问题可能无法缓解症状。
我不能让这些方法工作,所以我最终做了以下。对于你最初想隐藏的元素:
<div <!--...--> style="display: none;" ng-style="style">
然后在你的控制器中,在顶部或顶部附近添加以下内容:
$scope.style = { display: 'block' };
这样,元素最初是隐藏的,只有当控制器代码实际运行时才显示。
您可以根据需要调整位置,也许还可以添加一些逻辑。在我的例子中,如果当前没有登录,我将切换到登录路径,并且不希望我的界面事先闪烁,因此我设置了$scope。样式后的登录检查。
确保AngularJS包含在HTML的头部。参见ngCloak文档:
为了得到最好的结果,angular.js脚本必须加载在头文件中 HTML文件的部分;或者,CSS规则(上面)必须是 包含在应用程序的外部样式表中。