我有一个问题在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>
当前回答
实际上有两个独立的问题会导致闪烁问题,你可能会面临其中一个或两个。
问题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-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的昂贵操作。这样做的代价是使用两个作用域变量来实现相同的目的,而不是一个,但到目前为止,这绝对是最好的选择。
虽然文档没有提到它,但添加display: none;规则到你的CSS。如果你在body中加载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的规则将优先,显示将被设置为block,因此您将在模板编译之前看到闪烁。
我尝试了这里发布的每一个解决方案,仍然在Firefox中闪烁。
如果它有助于任何人,我通过添加style="display: none;"到主要内容div,然后使用jQuery(我已经在页面上使用它)$('#main-div-id').show();一旦从服务器获取数据后加载了所有内容;
实际上,我发现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已经获得了控制权。
我有一个类似的问题,并发现如果你有一个类包含过渡,元素将闪烁。我试图添加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