Angularjs-ng-плащ/ng-показать элементы мигают

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

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

пример:

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

29 ответов


хотя в документации об этом не упоминается, может быть недостаточно добавить 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 element

.nav > li > a {
  display: block;
}

Итак, если вы включаете правило, с просто display: none;, правило Bootstrap будет иметь приоритет и display будет установлен в block, поэтому вы увидите мерцание перед компиляцией шаблона.


As указано в документации, вы должны добавить правило в свой CSS, чтобы скрыть его на основе :

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

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

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


убедитесь, что AngularJS включен в head HTML. См.ngCloak док:

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


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

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

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

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


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-cloak...

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

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

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


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

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


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

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


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

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

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

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

Проблема 2: ng-плащ удаляется слишком рано

эта проблема, скорее всего, возникнет, когда у вас много 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>

(вам нужно сохранить ng-cloak чтобы избежать проблемы 1).

тогда в вашем приложении.run set isPageFullyLoaded:

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

имейте в виду, что в зависимости от того, что вы делаете, приложение.run может быть или не быть лучшим местом для установки isPageFullyLoaded. Важно убедиться, что isPageFullyLoaded получает значение true после того, как все, что вы не хотите мерцать, готово к раскрытию пользователю.

звучит как


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


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

с моим запуском с мерцанием я тестировал с открытыми DevTools и отключенным кэшем. Оставив панель закрытой с включенным кэшированием, исправлена моя проблема.


сохранение приведенных ниже операторов в теге head исправлена эта проблема

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

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


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


Я использую Ionic framework, добавление стиля 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


вам лучше ссылаться на угловой документ, потому что версия[1.4.9] имеет обновление ниже, которое может поддерживать директиву data-ng-cloak.

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

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

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

затем в контроллере добавьте это вверху или рядом с ним:

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

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

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


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

Я бы завернул <ul> с <div ng-cloak>


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

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

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

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

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


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

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


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

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

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

прежде чем я понял, что могу явно встроить стиль CSS в страницу, Я попытался выяснить, почему ng-cloak не выполняет свою работу. Потратив час в никуда, я наконец решил просто вручную спрятать и показать контейнер. Идея проста-сначала скрыть контейнер, а затем показать его после того, как угловой сделал свою первоначальную обработку и удаление разметки шаблона из страница.

Вы можете вручную скрыть содержимое, и сделать его видимым после углового получил контроль. Для этого я использовал:

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

обратите внимание на отображение: нет стиля, который явно скрывает элемент изначально на странице.

затем, как только Angular запустит свою инициализацию и эффективно обработает разметку шаблона на странице, вы можете показать содержимое. Для углового это "готовое" событие-приложение.функция run ():

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

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


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


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

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


Я лично решил использовать , а не 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.


пробовал ng-cloak но все-таки кратко мигает. Ниже кода избавьте их полностью.

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

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

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

по существу, когда область.часы срабатывают в этом случае, AngularJS отслеживает изменения в переменной name (model.значение)


избежать разрыва строки

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