我在angular.js中使用指令/类ng-cloak
或的问题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-cloak
或的问题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>
Answers:
尽管文档中没有提及,但仅将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;
simple中包含一个规则,Bootstrap的规则将具有优先级,并且display
会被设置为block
,因此您将在模板编译之前看到闪烁。
:
在ng:cloak
没有正确转义。对于纯CSS,请确保存在反斜杠。对于已编译的CSS,例如Stylus,它将为[ng\\:cloak]
。检查您编译的CSS,以确保它是正确的。
如文档中所述,您应该在CSS上添加一个规则以基于ng-cloak
属性将其隐藏:
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none;
}
我们在“使用Angular构建”网站上使用了类似的技巧,您可以在Github上查看其来源:https : //github.com/angular/builtwith.angularjs.org
希望有帮助!
确保AngularJS包含在head
HTML中。参见ngCloak doc:
为了获得最佳结果,必须将angular.js脚本加载到html文件的头部;或者,必须在应用程序的外部样式表中包含上述css规则。
ng-cloak
现在在工作。
head
在样式表中包含但之后包含Angular 并不能解决问题。
使用ngCloak从来没有让我很幸运。尽管上述所有内容,我仍然会忽悠。避免轻拂的唯一肯定方法是将您的内容放入模板中并包括该模板。在SPA中,唯一由Angular编译之前将被评估的HTML是您的主要index.html页面。
只需将体内的所有东西都粘在一个单独的文件中,然后:
<ng-include src="'views/indexMain.html'"></ng-include>
您永远都不会那样闪烁,因为Angular在将模板添加到DOM之前会对其进行编译。
ng-include
产生一个额外的AJAX请求,以从服务器获取内容。例如,我了解了一种绝不应该ng-include
在内部使用的艰难方法ng-repeat
。
ng-app
外面ng-include
在您的标记。
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-bind
这是避免“大括号闪烁”或不得不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-cloak失败,但是通过删除过渡按钮停止了闪烁。
我正在使用离子框架,按钮轮廓具有此过渡
.button-outline {
-webkit-transition: opacity .1s;
transition: opacity .1s;
}
只需覆盖该类以删除过渡,按钮将停止闪烁。
更新资料
同样,在使用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
.button-clear, .button-icon, .button-outline { @include transition(opacity 0s); }
到我的scss。
我有一个问题 <div ng-show="expression">
,即即使ng-show指令有机会运行之前,即使“ expression”最初是假的,a最初也会在不到一秒钟的时间内可见。
我使用的解决方案是手动添加“ ng-hide”类(如中)<div ng-show="expression" ng-hide>
,以确保其最初开始处于隐藏状态。之后,ng-show指令将根据需要添加/删除ng-hide类。
尝试关闭Firebug。我是认真的。这对我来说很有帮助。
应用接受的答案,然后确保Firefox 中的Firebug已关闭:按F12键,然后关闭此页面的Firebug-右上角的小按钮。
实际上,有两个单独的问题可能导致闪烁问题,您可能会遇到其中一个或两个。
问题1:应用ng-cloak太晚
解决此问题的方法已在此页上的许多答案中进行了描述,以确保将AngularJS加载到头部。参见ngCloak doc:
为了获得最佳结果,必须将angular.js脚本加载到html文件的头部;或者,必须在应用程序的外部样式表中包含上述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的解决方案为时已晚,然后将其移除。仅解决这些问题之一可能无法缓解症状。
我们在公司遇到了这个问题,并通过为闪烁的ng-show元素的CSS样式添加“ display:none”来解决了这个问题。我们根本不需要使用ng-cloak。与该线程中的其他线程不同,我们在Safari中遇到了此问题,但在Firefox或Chrome中却没有遇到过这个问题-可能是由于Safari在iOS7中的懒惰重绘错误所致。
最好使用ng-if
代替ng-show
。ng-if
完全删除并重新创建DOM中的元素,并有助于避免ng-show闪烁。
我使用的是离子框架,在某些情况下可能无法添加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_WeyaVzdixJ8 = onepage&q = ng-show%20hide%20flickering%20in%20ios&f = false
除了其他答案以外,如果您发现模板代码仍在闪烁,则很有可能您的脚本位于页面底部,这意味着直接将ng-cloak指令无效。您可以将脚本移到最前面,也可以创建CSS规则。
文档说:“为了获得最佳结果,必须将angular.js脚本加载到html文档的头部;或者,上述css规则必须包含在应用程序的外部样式表中。”
现在,它不必是外部样式表,而只需在头部的一个元素中即可。
<style type="text/css">
.ng-cloak {
display: none !important;
}
</style>
我尝试过这里发布的所有解决方案,但在Firefox中仍然闪烁。
如果对任何人都有style="display: none;"
用,我可以通过添加到主要内容div中来解决它,然后$('#main-div-id').show();
在从服务器获取数据后加载所有内容,然后使用jQuery(我已经在页面上使用过它)了。
我实际上发现Rick Strahl的Web日志中的建议完美地解决了我的问题(因为有时ng-cloak闪烁原始{{code}}仍然很奇怪,尤其是在运行Firebug时):
核选项:手动隐藏内容
使用显式CSS是最佳选择,因此以下内容永远都不是必需的。但我将在这里提及它,因为它提供了一些见识,使您可以了解如何在加载其他框架时或在您自己的基于标记的模板中手动隐藏/显示内容。
在我确定可以将CSS样式明确地嵌入到页面之前,我曾尝试弄清ng-cloak为什么不做它的工作。在浪费了一个小时之后,我终于决定只手动隐藏并显示容器。这个想法很简单–首先隐藏容器,然后在Angular完成初始处理并从页面中删除模板标记后再显示它。
您可以手动隐藏内容,并在Angular获得控制后使其可见。为此,我使用了:
<div id="mainContainer" class="mainContainer boxshadow"
ng-app="app" style="display:none">
请注意显示:none样式最初在页面上显式隐藏了元素。
然后,一旦Angular运行了其初始化并有效地处理了页面上的模板标记,便可以显示内容。对于Angular,此“就绪”事件是app.run()函数:
app.run( function ($rootScope, $location, cellService) {
$("#mainContainer").show();
…
});
这有效地删除了display:none样式和内容显示。到app.run()触发时,DOM已准备好显示已填充数据或至少为空数据– Angular已获得控制权。
从上面的讨论
[ng-cloak] {
display: none;
}
是解决问题的完美方法。
我在指令中使用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插入操作。这是以牺牲两个作用域变量用于同一目的而不是一个目的为代价的,但是到目前为止,这绝对是最好的选择。
上面列出的解决方案都不适合我。然后,我决定查看实际功能,并意识到,当“ $ scope.watch”被触发时,它是在name字段中输入了一个值,但实际情况并非如此。所以在代码中我设置了oldValue和newValue然后
$scope.$watch('model.value', function(newValue, oldValue) {
if (newValue !== oldValue) {
validateValue(newValue);
}
});
本质上,在这种情况下,在触发scope.watch时,AngularJS监视对名称变量(model.value)的更改