Angularjs-ng-cloak / ng-show要素が点滅する


231

ディレクティブ/クラスng-cloakまたはを使用したangular.jsに問題があり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
これらの要素に最初にdisplay:noneスタイルを設定すると、問題は解決しますか?
akonsu

3
私はそれを試します、私はクラスを追加することで同様のことを試みました(それは要素を隠す)そしてそれから手動でjsを介してそれを削除しました、しかしそれはさらにもっと悪く見えました。
MelkorNemesis

回答:


385

ドキュメントにはそれが記載されていませんが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ため、テンプレートがコンパイルされる前にフリッカーが表示されます。


3
また、require.jsなどの非同期ローダーを使用してangular.jsをロードする場合、.jsのcssルールが時間内に解析されないため、この同じ問題が発生する可能性があることに注意してください。上記のソリューションはこのシナリオも修正します。
Johann

84
私の問題は解決しません。わからない-私はブラウザが最初に物事を表示するには熱心すぎると思います...
Andriy Drozdyuk

7
ブラウザは、最初のパスであっても、CSSを考慮せずにDOMをレンダリングしてはなりません。それは非常に非効率的です。セットアップを再確認してください:p
AlexG

1
domsモジュールコードを遅延ロードした後、ng-cloakされたdomをどのように再ブートしますか?
FutuToad 14年

上記のcssが機能しない場合は、適切にエスケープさ:ng:cloakていない可能性があります。純粋なCSSの場合は、バックスラッシュがあることを確認してください。コンパイルされたcss、たとえばスタイラスの場合はになります[ng\\:cloak]。コンパイル済みのCSSをチェックして、正しいことを確認してください。
ジョー

47

ドキュメントに記載、あなたがに基づいて、それを隠すために、あなたのCSSにルールを追加する必要がありますng-cloak属性:

[ng\:cloak], [ng-cloak], .ng-cloak {
    display: none;
}

「Built with Angular」サイトでも同様のトリックを使用しており、Githubのソースを表示できます。https//github.com/angular/builtwith.angularjs.org

お役に立てば幸いです。


4
angular.jsは、そのスタイルルールをドキュメントの先頭に追加します。これをCSSに追加する必要はありません。とはいえ、これはうまくいくようです。私の推測は、angular.jsはangularをロードするまでスタイルブロックをヘッドに追加しないためです。
ntownsend 2012

13
本当にドキュメントに記載することはこれです:「最良の結果については、angular.jsスクリプトは、HTMLファイルのheadセクションにロードされなければならない。その代わりに、(上記の)CSSルールは、アプリケーションの外部スタイルシートに含まれている必要があります。 」
Andriy Drozdyuk 2013

4
つまり、ページの下部にスクリプト参照を追加する場合(多くの人が行うように)、次に、ルールをCSSに追加します。
GFoley83 2013

1
require.jsでangular.jsを追加していたので、これが役立ちました。
オリーブ

1
ng-appディレクティブを格納するhtml要素にng-cloakディレクティブを追加しました。魅力のように働いた。例:<div ng-cloak ng-app = "my-app">
miniscem

33

AngularJSがheadHTMLのに含まれていることを確認してください。ngCloak docを参照してください:

最良の結果を得るには、angular.jsスクリプトをHTMLファイルのヘッドセクションにロードする必要があります。または、CSSルール(上記)をアプリケーションの外部スタイルシートに含める必要があります。


3
はい!ページの最後にangular.jsをロードすることをお勧めしている人々がいる理由を理解できません。Angularが最初からコントロールを握っていれば気分が良くなります。私ng-cloakは今働いています。
Ivan Ferrer Villa

2
同意する-スクリプトが最後に読み込まれるということは、通常のWeb開発に由来するもので、jsが実行する前にページに何かを表示させたいのですが、angularの場合は実際には逆にしたいのです。
シャープに見

1
そして、スタイルシートがロードされる前。Angularをheadスタイルシートにインクルードした後でインクルードしても、問題は修正されません。
AgmLauncher 2016年

27

私はngCloakを使って多くの幸運を経験したことがありません。上記のすべてにもかかわらず、私はまだちらつきを取得します。フリックを回避する唯一の確実な方法は、コンテンツをテンプレートに入れ、テンプレートを含めることです。SPAでは、Angularによってコンパイルされる前に評価される唯一のHTMLは、メインのindex.htmlページです。

体の中のすべてのものを取り出して、別のファイルに貼り付けてください:

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

AngularはテンプレートをDOMに追加する前にコンパイルするので、そのようなちらつきは決して発生しないはずです。


1
正確に私が使用するもの-クリーンでシンプル、苦痛なハックはありません。
Dmitri Zaitsev 2014

2
ng-includeがサーバーからコンテンツをフェッチするために追加のAJAXリクエストを生成することに注意してください。たとえば、ng-include内部ng-repeatでは絶対に使用してはいけないという難しい方法を学びました。
jsuddsjr 2014年

1
私のために働いた。マークアップng-appではの外に置くことを忘れないng-includeでください。
GraehamF 2015年

2
このソリューションは、問題なく、最も効果的に機能します。可能であれば、このソリューションを使用してください。
idungotnosn 2015

2
このソリューションは、本当に煩わしい状況を修正しました。ありがとうございました!
Maxwelll 2016

22

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>

1
素敵でシンプルな答え。ng-bind「中括弧フラッシュ」を回避したりng-cloak、タグレベルで使用しなければならないのは良い方法ですが、コードを読みにくくする人もいます。彼らにとって、2つのアプローチを混在させない理由はわかりません。
Dave Everitt 2013年

1
他の回答では最初の角度をロードする必要があるため、ng-bindは問題に対するはるかに優れたアプローチであり、どのような状況でも中括弧がフラッシュすることはありません
legramira

20

ng-cloakをトリガーする別の方法を使用している場合、受け入れられた回答に加えて...

また、CSS / LESSにいくつかの特殊性を追加することもできます。

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

1
これは私の使用例ではうまくいきました。
Porlune 16

15

同様の問題があり、トランジションを含むクラスがある場合、要素が点滅することがわかりました。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


1
しかし、それはng-hide / showディレクティブのアニメーションを無効にしませんか?
Kushagra Gour 2015

1
思い出せない。試してみましたが、アニメーションが無効になっていますか?
Seb Fanals 2015

1
ありがとう。これはイオンの非常に特別な問題です。.button-clear, .button-icon, .button-outline { @include transition(opacity 0s); }私のscss に追加しました。
hgoebl 2015年

9

<div ng-show="expression">ng-showディレクティブが実行される前に、「式」が最初はfalseだったとしても、最初はほんの一瞬でが表示されるという問題がありました。

私が使用した解決策は、「ng-hide」クラスを手動で追加して、<div ng-show="expression" ng-hide>最初に非表示になっていることを確認することでした。ng-showディレクティブは、その後、必要に応じてng-hideクラスを追加/削除します。


1
うわー、私が試したすべての恐ろしいオプションのうち、これはトリックをしました。ありがとうございました!
ニコラ

最高のソリューション!これは私を数ヶ月狂わせました!ありがとうございました!
abelabbesnabi 2016年

私はイオンフレームワークを使用していますが、これが実際に機能する唯一の答えです
Mikel

7

Firebugをオフにしてみてください。私は真剣です。これは私の場合に役立ちます。

承認された回答を適用し、FirefoxのFirebugオフになっていることを確認します。F12を押してから、このページのFirebugをオフにします-右上隅にある小さなボタン。


うん、それは私のためにそれをやったありがとう
MadeInDreams 2016

ありがとう、それは私を夢中にさせていました。奇妙なバグ
スティーブンシンプソン

6

ちらつきの問題を引き起こす可能性のある2つの個別の問題が実際にあり、これらのいずれかまたは両方に直面している可能性があります。

問題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を適用するのが遅すぎて、すぐに削除されるようにしてください。これらの問題の1つだけを解決しても、症状が緩和されない場合があります。


1
これは私のためにそれを修正しました「スクリプトはヘッドセクションにロードされなければなり
aliopi 2017


3

それだけの価値があるので、ng-cloakが機能しないという同様の問題がありました。キャッシュが有効になっているアプリ/サイトをチェックして、ソースファイルを再利用し、それが役立つかどうかを確認することは価値があります。

ちらつきのある慣らしで、私はDevToolsを開いてキャッシュを無効にしてテストしていました。キャッシュを有効にしてパネルを閉じたままにすると、問題が解決しました。


3

以下のステートメントをヘッドタグに保持すると、この問題が修正されました

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

公式ドキュメント


3

これらのメソッドを機能させることができなかったので、最終的に次のことを行いました。最初に非表示にする要素の場合:

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

次に、コントローラで、これを上部または上部に追加します。

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

このように、要素は最初は非表示になっており、コントローラーコードが実際に実行されたときにのみ表示されます。

必要に応じて配置を調整し、ロジックを追加することができます。私の場合、現在ログインしていない場合はログインパスに切り替え、事前にインターフェイスがちらつくことを望まないので$scope.style、ログインチェック後に設定しました。


2

ng-if代わりに使用することをお勧めしますng-showng-if DOM内の要素を完全に削除して再作成し、ng-showsの点滅を回避するのに役立ちます。


しかし、domのその部分で実行中のプラグインもすべて破壊します...(例:jquery ui)
Geert Bellemans

2

私はイオンフレームワークを使用していますが、CSSスタイルを追加すると特定の状況では機能しない場合があります。ng-show/ ng-hideの代わりにng-ifを使用してみてください。

ref: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_WeyaVz= vxdxdxen_exc_&&& = = onepage&q = ng-show%20hide%20flickering%20in%20ios&f = false


2

角度のあるドキュメントを参照するほうがよいでしょう。バージョン[1.4.9]がdata-ng-cloakディレクティブをサポートできるように、以下に更新されているためです。

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

2

上記のng-cloakソリューションを試しましたが、Firefoxで断続的な問題がまだあります。私にとってうまくいった唯一の回避策は、Angularが完全に読み込まれるまでフォームの読み込みを遅らせることです。

アプリにng-initを追加し、フォーム側でng-ifを使用して、設定した変数が既に読み込まれているかどうかを確認しました。

<div ng-app="myApp" ng-init="loaded='yes'"> 
   <form ng-if="loaded.length > 0">
      <!--all my elements here-->
   </form>
</div>

1

他の回答に加えて、テンプレートコードのフラッシュがまだ発生している場合は、ページの下部にスクリプトがある可能性があります。つまり、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


1

ここに投稿されたすべての解決策を試しましたが、Firefoxでちらつきが発生しました。

それがだれにも役立つ場合は、style="display: none;"メインコンテンツのdivに追加し$('#main-div-id').show();、サーバーからデータを取得した後にすべてが読み込まれたら、jQueryを使用して解決しました(既にページで使用していました)。


これが私に有効な唯一のソリューションであることがわかりましたが、JQueryの使用を避けたいので、代替案を見つけました。ここで私の答えを参照してください:stackoverflow.com/a/42527700/4214694
Andrew Downes

1

私は実際にRick StrahlのWebログからの提案が私の問題を完全に修正したことを発見しました(まだFirebugを実行しているときに、ng-cloakがraw {{code}}を点滅するという奇妙な問題が時々ありました)。

核のオプション:コンテンツを手動で隠す

明示的なCSSを使用するのが最良の選択なので、以下は必要ありません。ただし、他のフレームワークのロード時に、または独自のマークアップベースのテンプレートでコンテンツを手動で非表示/表示する方法についての洞察が得られるため、ここで触れておきます。

CSSスタイルをページに明示的に埋め込むことができることに気付く前に、ng-cloakが機能しない理由を理解しようとしました。1時間無駄になってしまった後、ようやく手動でコンテナーを非表示にして表示することにしました。アイデアは単純です。最初にコンテナを非表示にし、Angularが初期処理を行い、ページからテンプレートマークアップを削除したら、コンテナを表示します。

コンテンツを手動で非表示にして、Angularが制御した後にコンテンツを表示することができます。これを行うために私は使用しました:

<div id="mainContainer" class="mainContainer boxshadow"
    ng-app="app" style="display:none">

display:noneスタイルに注目してください。このスタイルでは、ページの最初の要素が明示的に非表示になっています。

次に、Angularが初期化を実行し、ページのテンプレートマークアップを効果的に処理したら、コンテンツを表示できます。Angularの場合、この「準備完了」イベントはapp.run()関数です。

app.run( function ($rootScope, $location, cellService) {        
    $("#mainContainer").show();
    
});

これにより、display:noneスタイルが効果的に削除され、コンテンツが表示されます。app.run()が発生するまでに、DOMはデータが入力されているか、少なくとも空のデータで表示される準備ができています。Angularは制御を取得しています。


これが私に有効な唯一のソリューションであることがわかりましたが、JQueryの使用を避けたいので、代替案を見つけました。ここで私の答えを参照してください:stackoverflow.com/a/42527700/4214694
Andrew Downes

1

上記の答えをすべて試しましたが、何もうまくいきませんでした。ionicを使用してハイブリッドアプリを開発し、エラーメッセージがちらつかないようにしようとしていました。 ng-hideクラスを要素に追加することで問題を解決しました。 私のdivには、エラーが発生したときに要素を表示するng-showがすでにあります。ng-hideを追加すると、angularが読み込まれる前にdivが表示されなくなります。NGクロークやヘッドに角度を追加する必要はありません。



1

ディレクティブでng-showを使用して、ポップアップの表示と非表示を切り替えています。

<div class="..." ng-show="showPopup">

上記のいずれもうまくいきませんでした。ng-showの代わりにng-ifを使用するのはやり過ぎです。これは、クリックするたびにポップアップコンテンツ全体を削除してDOMに追加することを意味します。代わりに、ng-ifを同じ要素に追加して、ドキュメントの読み込み時に表示されないようにします。

<div class="..." ng-show="showPopup" ng-if="popupReady">

その後、タイムアウトを指定して、このディレクティブを担当するコントローラーに初期化を追加しました。

$timeout(function () {
    $scope.popupReady = true;
});

このようにして、ちらつきの問題を排除し、クリックごとにDOM挿入のコストのかかる操作を回避しました。これは、1つではなく同じ目的で2つのスコープ変数を使用することを犠牲にして行われましたが、これまでのところ、これは間違いなく最良のオプションです。


1

試しましたng-cloakが、まだ短い点滅をしました。以下のコードはそれらを完全に取り除きました。

<body style="display:none;" ng-style="{'display':'block'}">

1

上記の解決策のどれも私にとってはうまくいきませんでした。次に、実際の関数を確認することにしました。「$ scope.watch」が起動されたときに、名前フィールドに値が設定されているのではないことに気づきました。だから私はコードでoldValueとnewValueを設定しました

$scope.$watch('model.value', function(newValue, oldValue) {
if (newValue !== oldValue) {
validateValue(newValue);
}
});

基本的に、この場合にscope.watchが発生すると、AngularJSは名前変数(model.value)への変更を監視します


0

でラップ<ul>します<div ng-cloak>


2
彼はをラップする必要はありません<ul>ng-cloak適用されている要素とその要素の子孫をクロークします。
btford 2012年

0

個人ではng-classなく、属性を使用することにしましたng-show。特にデフォルトで常に表示されないポップアップウィンドウの場合は特に、この方法で多くの成功を収めてきました。

昔は <div class="options-modal" ng-show="showOptions"></div>

今です: <div class="options-modal" ng-class="{'show': isPrintModalShown}">

options-modalクラスのCSSはdisplay: noneデフォルトです。showクラスにはdisplay:blockCSS が含まれています。


-2

改行しない

<meta http-equiv="Content-Security-Policy"              content="
default-src 'FOO';   
script-src 'FOO';    
style-src  'FOO'; 
font-src 'FOO';">

Firefox 45.0.1で動作します

<meta http-equiv="Content-Security-Policy"              content="    default-src 'FOO';    script-src 'FOO';     style-src  'FOO';    font-src 'FOO';">
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.