web-dev-qa-db-ja.com

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

Angular.jsにディレクティブ/クラスng-cloakまたはng-showがあります。

Chromeは正常に動作しますが、Firefoxはng-cloakまたはng-showを持つ要素の瞬きを引き起こしています。私見はng-cloak/ng-showstyle="display: none;"に変換することによって引き起こされます、おそらくFirefox javascriptコンパイラは少し遅いです、それで、要素はしばらくの間現れて、それから隠れますか?

例:

<ul ng-show="foo != null" ng-cloak>..</ul>
226
MelkorNemesis

ドキュメントには記載されていませんが、CSSにdisplay: none;ルールを追加するだけでは不十分な場合があります。あなたが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のルールが優先され、displayblockに設定されるため、テンプレートがコンパイルされる前にちらつきが表示されます。

383
Tim Schaub

documentation で説明されているように、CSSにng-cloak属性に基づいてそれを隠すためのルールを追加する必要があります。

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

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

それが役立つことを願っています!

46
btford

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

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

32
Andriy Drozdyuk

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

本体内のすべてのものを取り出して別のファイルに貼り付けるだけです。

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

AngularはテンプレートをDOMに追加する前にコンパイルするので、そのようにちらつくことは決してありません。

27
Matt Hughes

ngBindngBindTemplate は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>
22
Mark Rajcok

Ng-cloakをトリガーする別の方法を使用しているのであれば、受け入れられている答えに加えて...

あなたはまたあなたのCSS/LESSにいくつかの追加の特殊性を加えることを望むかもしれません:

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

私は同様の問題を抱えていて、トランジションを含むクラスがあると要素が点滅することを発見しました。 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

15
Seb Fanals

Ng-showディレクティブを実行する機会が得られる前に、 "expression"が最初はfalseであったとしても、最初は<div ng-show="expression">が一瞬で表示されるという問題がありました。

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

9
metamatt

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

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

7
CoperNick

ちらつきの問題を引き起こす可能性がある実際には2つの別々の問題があり、あなたはこれらのどちらか一方または両方に直面する可能性があります。

問題1:ng-cloakの適用が遅すぎます

このページの多くの答えで説明されているように、この問題はAngularJSが頭の中にロードされていることを確認することで解決されています。 ngCloak doc を参照してください。

最良の結果を得るには、angular.jsスクリプトをhtmlファイルのheadセクションにロードする必要があります。あるいは、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>

(問題1を回避するためにng-cloakを保持する必要があります)。

次にapp.runにisPageFullyLoadedを設定します。

app.run(['$rootScope', function ($rootScope) {
    $rootScope.$safeApply = function (fn) {
        $rootScope.isPageFullyLoaded = true;
    }
}]);

実際の作業内容によっては、app.runがisPageFullyLoadedを設定するのに最適な場所である場合とそうでない場合があることに注意してください。重要なことは、ちらつきたくないものがユーザに明らかにされる準備が整った後にisPageFullyLoadedがtrueに設定されることを確実にすることです。

問題1は、OPが打っている問題ですが、他の人は、解決策がうまくいかない、または部分的にしかうまくいかないことを見つけていますProblem 2代わりにまたは同様に。

重要な注意:ng-cloakの適用が遅すぎたり、すぐに削除されたりする場合は、必ず解決策を適用してください。これらの問題のうち1つだけを解決しても、症状が緩和されるわけではありません。

6
Andrew Downes

当社でこの問題に遭遇し、ちらつきのあるng-show要素のCSSスタイルに "display:none"を追加して解決しました。 ng-cloakを使う必要はまったくありませんでした。このスレッドの他のスレッドとは異なり、この問題はSafariでは発生しましたがFirefoxやChromeでは発生しませんでした - おそらくiOS7での Safariのlazy repaintバグ が原因です。

4
Jake McGuire

それが価値があるもののために、私はng-cloakが働かないという同様の問題を抱えていました。それが役立つかどうかを確認するためにソースファイルを再利用するためにキャッシュを有効にしてあなたのアプリ/サイトをチェックする価値があるかもしれません。

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

3
mrdazm

Headタグ内に以下のステートメントを保持することで、この問題は解決しました

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

公式文書

3
Saikiran K

私はこれらの方法のどれもうまく機能させることができなかったので、私は結局次のことをしました。あなたが最初に隠したい要素のために:

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

それからあなたのコントローラーで、一番上かその近くにこれを追加してください:

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

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

ロジックを追加して、配置をニーズに合わせて調整できます。私の場合は、現在ログインしていない場合はログインパスに切り替えます。また、事前に自分のインターフェイスを点滅させたくない場合は、ログインチェック後に$scope.styleを設定します。

3
shawkinaw

私はイオンフレームワークを使用しています、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_WeyaVzdixJ8k&hl = ja&sa = X&redir_esc = y#v =ワンページ&q = ng-show%20hide%20flcering%20in%20ios&f = false

2
d1ck50n

私は上記の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>
2
java25

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

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

ng-ifの代わりにng-showを使用することをお勧めします。 ng-ifはDOM内の要素を完全に削除して再作成し、ng-showsが点滅しないようにします。

2
alexey

上記の議論から

[ng-cloak] {
                display: none;
            }

問題を解決するための完璧な方法です。

1
Dinesh Jain

上記の解決策のどれも私のために働きませんでした。私はそれから実際の関数を見ることに決めました、そして、“ $ scope.watch”が発火されたとき、それがそうであることを意味していなかった名前フィールドに値を入れていたことに気づきました。それで私が設定したコードとoldValueとnewValue

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

この場合、本質的にscope.watchが起動されると、AngularJSは名前変数(model.value)への変更を監視します。

1
D.Adelakun

他の答えに加えて、テンプレートコードのフラッシュがまだ発生していることがわかった場合は、スクリプトがページの下部に表示されている可能性があります。つまり、ng-cloakディレクティブは正しく動作しません。あなたは自分のスクリプトを頭に動かすかCSSルールを作成することができます。

「最良の結果を得るには、angle.jsスクリプトをhtml文書のheadセクションにロードする必要があります。あるいは、上記のCSSルールをアプリケーションの外部スタイルシートに含める必要があります。」

今、それは外部スタイルシートである必要はありませんが、頭の中の要素の中だけです。

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

ソース: https://docs.angularjs.org/api/ng/directive/ngCloak

1
Elijah Lynn

私は上記のすべての答えを試しましたが、何もうまくいきませんでした。イオンを使用してハイブリッドアプリを開発し、エラーメッセージを点滅させないようにしていました。 要素にng-hideクラスを追加して問題を解決しましたエラー。 ng-hideを追加すると、角度が読み込まれる前にdivが表示されないように設定されます。頭に角度をつけたり、角度をつけたりする必要はありません。

1
gyleg5

ここに投稿されたすべてのソリューションを試してみましたが、Firefoxでちらつくことがありました。

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

1
hipnosis

ポップアップの表示と非表示を切り替えるディレクティブで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
downhand

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

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

私は実際に Rick Strahlのウェブログ からの提案が私の問題を完全に解決しているのを見つけました(未だにng-cloakの未加工の点​​滅{{code}の奇妙な問題がありました)。時々、特にFirebugを実行している間:

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

明示的なCSSを使用するのが最良の選択なので、次のことが必要になることは決してありません。しかし、他のフレームワークのロード時に、または独自のマークアップベースのテンプレートで、コンテンツを手動で非表示/表示する方法についてある程度の洞察を与えるので、ここでそれについて言及します。

CSSスタイルをページに明示的に埋め込むことができると考える前に、ng-cloakがなぜその仕事をしていないのかを理解しようとしました。どこにも行かなくなって1時間を無駄にした後、私はついに手動でコンテナを隠して表示することにしました。考え方は簡単です - 最初はコンテナを非表示にしてからAngularが最初の処理を行い、ページからテンプレートマークアップを削除したらそれを表示します。

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

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

表示に注意してください。ページ上の最初の部分で明示的に要素を非表示にするnoneスタイル。

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

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

これは事実上表示を取り除きます:noneスタイルとコンテンツ表示。 app.run()が起動するまでに、DOMはいっぱいになったデータまたは少なくとも空のデータで表示される準備ができています - Angularは制御を取得しました。

1
Campbeln

私は個人的に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:block CSSが含まれています。

私は<ul><div ng-cloak>でラップするでしょう

0
Dan Doyon