Элементы Angularjs - ng-cloak/ng-show мигают

У меня проблема в angular.js с директивой/классом ng-cloak или ng-show.

Chrome работает отлично, но Firefox вызывает мигание элементов с помощью ng-cloak или ng-show. IMHO вызвано преобразованием ng-cloak/ng-show в style="display: none;", возможно, компилятор Firefox javascript немного медленнее, поэтому элементы появляются некоторое время, а затем скрываются?

Пример:

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

Ответ 1

Хотя документация не упоминает об этом, может быть недостаточно добавить правило 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;, правило Bootstrap будет иметь приоритет, а display будет установлено на block, поэтому вы увидите мерцание перед компиляцией шаблона.

Ответ 2

Как упомянутый в документации, вы должны добавить правило к своему CSS, чтобы скрыть его на основе атрибута ng-cloak:

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

Мы используем подобные трюки на сайте "Built with Angular", который вы можете просмотреть в Github: https://github.com/angular/builtwith.angularjs.org

Надеюсь, что это поможет!

Ответ 3

Удостоверьтесь, что параметр "Угловое" включен в head HTML. См. ngCloak doc:

Для достижения наилучшего результата angular.js script должен быть загружен в голову раздел html файла; в качестве альтернативы, правило css (выше) должно быть включены во внешнюю таблицу стилей приложения.

Ответ 4

Мне никогда не удавалось использовать ngCloak. Я все еще мерцаю, несмотря на все, что упоминалось выше. Единственный верный способ избежать щелчка - разместить свой контент в шаблоне и включить шаблон. В SPA единственный HTML-код, который будет оцениваться до компиляции с помощью Angular, является вашей главной страницей index.html.

Просто возьмите все внутри тела и вставьте его в отдельный файл, а затем:

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

Вы никогда не должны мерцать таким образом, поскольку Angular скомпилирует шаблон перед добавлением его в DOM.

Ответ 5

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>

Ответ 6

В дополнение к принятому ответу, если вы используете альтернативный метод запуска ng-cloak...

Вы также можете добавить некоторые дополнительные особенности в свой CSS/LESS:

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

Ответ 7

У меня была аналогичная проблема, и выяснилось, что если у вас есть класс, содержащий переходы, элемент будет мигать. Я попытался добавить ng-плащ без успеха, но, удалив переход, кнопка перестала мигать.

Я использую ионную структуру, и кнопка-схема имеет этот переход

.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

Ответ 8

У меня возникла проблема, когда <div ng-show="expression"> был первоначально видимым на долю секунды, даже если "выражение" было изначально ложным, прежде чем директива ng-show получила возможность запускать.

Решением, которое я использовал, было вручную добавить класс "ng-hide", как в <div ng-show="expression" ng-hide>, чтобы убедиться, что он начал изначально скрываться. Директива ng-show добавит/удалит класс ng-hide по мере необходимости после этого.

Ответ 9

Попробуйте отключить Firebug. Я серьезно. Это помогает в моем случае.

Примените принятый ответ, а затем убедитесь, что Firebug в Firefox отключен выключен: нажмите F12, затем отключите Firebug для этой страницы - маленькую кнопку в правом верхнем углу.

Ответ 10

Мы столкнулись с этой проблемой в нашей компании и решили ее, добавив "display: none" к стилю CSS для тех мерцающих элементов ng-show. Нам не пришлось вообще использовать ng-cloak. В отличие от других в этом потоке, мы столкнулись с этой проблемой в Safari, но не с Firefox или Chrome - возможно, из-за Safari lazy repaint bug в iOS7.

Ответ 11

На самом деле есть две отдельные проблемы, которые могут вызвать проблему мерцания, и вы можете столкнуться либо с одним, либо с обоими из них.

Проблема 1: ng-cloak применяется слишком поздно

Эта проблема решается, поскольку во многих ответах на этой странице описано, что AngularJS загружается в голову. См. ngCloak doc:

Для достижения наилучшего результата angular.js script должен быть загружен в голову раздел 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, необходимо сохранить ng-cloak.

Затем в вашем приложении 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, так и к использованию слишком поздно и удаляться в ближайшее время. Решение только одной из этих проблем не может облегчить симптомы.

Ответ 12

Для чего это стоит, у меня была аналогичная проблема, но ng-cloak не работал. Возможно, стоит проверить, что ваше приложение/сайт с кешем включено для повторного использования исходных файлов, чтобы узнать, помогает ли это.

С моим запуском с мерцанием я тестировал DevTools open и кеш отключен. Выход из закрытой панели с кешированием позволил устранить мою проблему.

Ответ 13

Сохранение приведенных ниже инструкций в главном теге устраняет эту проблему

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

официальная документация

Ответ 14

Лучше использовать ng-if вместо ng-show. ng-if полностью удаляет и воссоздает элемент в DOM и помогает избежать моргания ng-show.

Ответ 15

Я использую ионную фреймворк, добавив, что CSS-стиль может не работать при определенных обстоятельствах, вы можете попробовать использовать ng-if вместо ng-show/ng-hide

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=en&sa=X&redir_esc=y#v=onepage&q=ng-show%20hide%20flickering%20in%20ios&f=false

Ответ 16

вам лучше обратиться к документу 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;
}

Ответ 17

Я не мог заставить любой из этих методов работать, поэтому в итоге я сделал следующее. Для элемента, который вы хотите сначала скрывать:

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

Затем в вашем контроллере добавьте это вверху или около нее:

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

Таким образом, элемент изначально скрыт и отображается только тогда, когда фактически выполняется код контроллера.

Вы можете настроить место размещения на свои нужды, возможно, добавив некоторую логику. В моем случае я переключаюсь на путь входа в систему, если не в настоящее время вошел в систему, и не хотел, чтобы мой интерфейс мерцал заранее, поэтому я установил $scope.style после проверки входа.

Ответ 18

Я попробовал решение 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>

Ответ 19

Я бы обернул <ul> с помощью <div ng-cloak>

Ответ 20

В дополнение к другим ответам, если вы обнаружите, что Flash-код шаблона все еще существует, вероятно, у вас есть ваши сценарии внизу страницы, а это значит, что директива ng-cloak прямо не работает. Вы можете либо переместить свои скрипты в голову, либо создать правило CSS.

В документах сказано: "Для достижения наилучшего результата angular.js script должен быть загружен в разделе заголовка html-документа, в качестве альтернативы, правило css выше должно быть включено во внешнюю таблицу стилей приложения."

Теперь он не должен быть внешней таблицей стилей, а просто элементом в голове.

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

источник: https://docs.angularjs.org/api/ng/directive/ngCloak

Ответ 21

Я пробовал каждое решение, размещенное здесь и все еще мелькнувшее в Firefox.

Если это кому-то помогает, я решил это, добавив style="display: none;" в основной контент div, а затем с помощью jQuery (я уже использовал его на странице) $('#main-div-id').show(); после того, как все было загружено после получения данных с сервера;

Ответ 22

Я действительно нашел предложение от Rick Strahl Web Log исправил мою проблему отлично (поскольку у меня все еще была странная проблема с ng-cloak, мигающим raw {{code}}, особенно при запуске Firebug):

Ядерный вариант: скрытие содержимого вручную

Использование явного CSS - лучший выбор, поэтому следующее не должно быть необходимым. Но я упоминаю об этом здесь, поскольку он дает некоторое представление о том, как можно скрыть/показать содержимое вручную при загрузке для других фреймворков или в собственных шаблонах на основе разметки.

Прежде чем я понял, что я могу явно вставить стиль CSS в страницу, я попытался выяснить, почему ng-cloak не выполнял свою работу. После того, как я потерял час, я, наконец, решил просто спрятать и показать контейнер. Идея проста - сначала скрыть контейнер, а затем показать его один раз, когда 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();
    …
});

Это эффективно удаляет отображение: нет стиля и содержимого. К моменту запуска app.run() DOM готов к отображению с заполненными данными или по крайней мере пустыми данными - Angular получил контроль.

Ответ 23

Я попробовал все ответы выше, и ничего не получилось. Использование ionic для разработки гибридного приложения и пыталось сделать сообщение об ошибке не мерцающим. Я решил решить проблему, добавив в свой элемент класс ng-hide. У моего div уже есть ng-show, чтобы показать элемент при возникновении ошибки. Добавление ng-hide устанавливает, чтобы div не отображался до загрузки angular. Нет ng-плаща или добавить angular в нужную голову.

Ответ 24

AS из приведенного выше обсуждения

[ng-cloak] {
                display: none;
            }

- идеальный способ решения проблемы.

Ответ 25

Я использую 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 при каждом нажатии. Это произошло за счет использования двух переменных области для одной и той же цели вместо одной, но пока это, безусловно, лучший вариант.

Ответ 26

Я лично решил использовать атрибут ng-class, а не ng-show. У меня был намного больше успеха в этом маршруте, особенно для всплывающих окон, которые по умолчанию не отображаются.

Что раньше было <div class="options-modal" ng-show="showOptions"></div>

теперь: <div class="options-modal" ng-class="{'show': isPrintModalShown}">

с CSS для параметра-модального класса display: none по умолчанию. Класс show содержит display:block CSS.

Ответ 27

Избегайте разрыва строки

<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';">