отключить nganimate для некоторых элементов


96

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

Спасибо.


1
Добавьте пример кода проблемы.
cheekybastard

Одна из проблем заключается в том, что ngAnimate воздействует display:blockна все ваши ретрансляторы:ng-hide-add-active, .ng-hide-remove { display: block!important; }
Somatik

Лучше задать вопрос: «Как я могу определить свой CSS, чтобы ngAnimate работал правильно для скрытых элементов без завершения полного цикла анимации». Лучший ответ - от Криса Барра ниже.
Эрик

Ответы:


53

Просто добавьте это в свой CSS. Лучше всего, если это будет последнее правило:

.no-animate {
   -webkit-transition: none !important;
   transition: none !important;
}

затем добавьте no-animateк классу элемента, который вы хотите отключить. Пример:

<div class="no-animate"></div>

2
Если вы используете sass, вам не нужен «-webkit-transition: none!
Important

15
Обратите внимание, что этот ответ неверен, потому что он ОТКЛЮЧАЕТ ВСЕ АНИМАЦИИ, а не только те, которые обрабатываются Angular.
stackular

1
Ты это пробовал? позвольте мне увидеть образец вашего кода. Это работает для меня и более шести человек, которые его одобрили,
Дэвид Аддотай,

2
Я добавил .no-animate, .no-animate-children *правило, касающееся детей и т. Д.
Кимбалл Робинсон

1
@DavidAddoteye это решение нежизнеспособно, если у вас есть ng-show или ng-if над элементом с переходом ... Я имею в виду ... если у меня есть счетчик загрузчика, который появляется только во время HTTP-запроса и исчезает, когда запрос разрешен, добавляя этот класс вообще не приведет к анимации !, ответ Майкла в порядке, но он слишком утомителен для реализации, и вам следует избегать использования селекторов css в контроллерах. Создание директивы - это нормально, но, посмотрев на ответ Блоузи, вы обнаружите, что команда AngularJS уже предоставила гибкий способ решить эту проблему;)
Эдриан

106

Если вы хотите включить анимацию для определенных элементов (в отличие от их отключения для определенных элементов), вы можете использовать $ animateProvider для настройки элементов с определенным именем класса (или регулярным выражением) для анимации.

Приведенный ниже код включит анимацию для элементов, имеющих angular-animateкласс:

var myApp = angular.module("MyApp", ["ngAnimate"]);
myApp.config(function($animateProvider) {
  $animateProvider.classNameFilter(/angular-animate/);
})

Вот пример разметки, которая включает angular-animateкласс для включения анимации:

<div ng-init="items=[1,2,3,4,5,6,7,8,9]">
  <input placeholder="Filter with animations." ng-model="f" /> 
  <div class="my-repeat-animation angular-animate" ng-repeat="item in items | filter:f track by item" >
    {{item}}
  </div>
</div>

Пример Plunker, заимствованный и измененный из этого блога, где только первый фильтр имеет анимацию (из-за наличия angular-animateкласса).

Обратите внимание, что я использую angular-animateв качестве примера, и он полностью настраивается с помощью .classNameFilterфункции.


5
Ты спас мне день. Большое спасибо
Густавохенке 08

Это наиболее элегантное решение, так как оно требует согласия на использование анимации, а анимированные элементы четко отличаются от других по имени класса.
Nikola M.

2
Это должно быть приемлемое решение. Отлично работает и спас мне день!

9
используйте /^(?:(?!ng-animate-disabled).)*$/регулярное выражение, чтобы отключить аннимацию с помощью ng-animate-disabledкласса.
IcanDivideBy0

Отличное решение! У меня есть разбитая на страницы таблица с 20 строками на странице. Треть времени на переключение страниц уходило на обработку браузером классов CSS анимации, которые даже не использовались.
Кевин

81

Есть два способа отключить анимацию в AngularJS, если у вас есть модуль ngAnimate в зависимости от вашего модуля:

  1. Отключить или включить анимацию глобально в сервисе $ animate:

    $animate.enabled(false);
  2. Отключите анимацию для определенного элемента - это должен быть элемент, для которого angular добавит классы css animationstate (например, ng-enter, ...)!

    $animate.enabled(false, theElement);

Начиная с версии Angular 1.4, вы должны изменить аргументы:

$animate.enabled(theElement, false);

Документация для$animate .


2
Это не работает с конкретными элементами, как ожидалось. Если я отключу глобальную анимацию, а затем включу ее для одного конкретного элемента, это не сработает.
Кушагра Гур

1
Этот ответ следует удалить или отредактировать, чтобы указать, на какой версии Angular он действительно работает. Для 1.2.10 это определенно не работает для выборочного включения анимации для определенных элементов, что и составляет весь смысл вопроса AFAICT.
Trindaz

Кто-нибудь знает, работает ли Вариант 2 на версии 1.2.25?
Хорват

1
Просто взглянув на документацию ( docs.angularjs.org/api/ng/service/$animate ), кажется, что «element» - это первый параметр, передаваемый включенной функции.
DanielM

49

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

Конфиг

    var myApp = angular.module("MyApp", ["ngAnimate"]);
    myApp.config(function($animateProvider) {
        $animateProvider.classNameFilter(/^(?:(?!ng-animate-disabled).)*$/);
    })

использование

Просто добавьте ng-animate-disabledкласс к любым элементам, которые вы хотите игнорировать с помощью ng-animate.


Кредит http://davidchin.me/blog/disable-nganimate-for-selected-elements/


7
Я считаю, что это самый правильный способ отфильтровать неганнимое поведение!
edrian

6
Для этого ответа стоило прокрутить.
Jossef Harush

Я могу подтвердить, что с последней версией AngularJS это определенно лучшее решение проблемы.
Адам Рейс

44

спасибо, я написал директиву, которую вы можете разместить на элементе

CoffeeScript:

myApp.directive "disableAnimate", ($animate) ->
  (scope, element) ->
    $animate.enabled(false, element)

JavaScript:

myApp.directive("disableAnimate", function ($animate) {
    return function (scope, element) {
        $animate.enabled(false, element);
    };
});

Это довольно изящный подход, не всегда ясно, как получить доступ к объекту элемента, и с некоторыми другими подходами, я боюсь, я загроможу свои контроллеры с помощью Javascript, жестко ссылающегося на один или несколько элементов, определенных в шаблоне . Это похоже на отличное разделение проблем, престиж!
Mattygabe

2
Порядок параметров в $ animate.enabled обратный, если кому-то интересно, почему это отключает всю анимацию ng. Работает как шарм, если использовать$animate.enabled(element,false);
gss 07

Извините, я вижу, что это применимо только к 1.4.x +, приведенный выше код верен для предыдущих версий.
gss 07

19

Я обнаружил, что это $animate.enabled(false, $element);будет работать для элементов, которые используют ng-showили, ng-hideно не будет работать для элементов, которые ng-ifпо какой-то причине используются! Решение, которое я в итоге использовал, заключалось в том, чтобы просто сделать все на CSS, о чем я узнал из этой темы на GitHub .

CSS

/* Use this for transitions */
.disable-animations.ng-enter,
.disable-animations.ng-leave,
.disable-animations.ng-animate {
  -webkit-transition: none !important;
  transition: none !important;
}

/* Use this for keyframe animations */
.disable-animations.ng-animate {
  -webkit-animation: none 0s;
  animation: none 0s;
}

SCSS

.disable-animations {
  // Use this for transitions
  &.ng-enter,
  &.ng-leave,
  &.ng-animate {
    -webkit-transition: none !important;
    transition: none !important;
  }
  // Use this for keyframe animations
  &.ng-animate {
    -webkit-animation: none 0s;
    animation: none 0s;
  }
}

В моем случае при загруженном ngAnimate класс вроде .loading.ng-hide оставался на экране до завершения полного цикла анимации. Это наиболее чистый ответ, потому что он просто передает правильную конфигурацию ngAnimate и использует ее в обычном режиме. Это предпочтительнее, чем его неверная конфигурация, а затем отключение. Так что +1 для вас, хотел бы я дать больше, чтобы сравнять счет.
Эрик

Это самый хитрый ответ. Делать это с помощью css лучше, чем возиться с js.
манас

Пожалуйста, посмотрите ответ @Blowsie, это более общий и правильный способ справиться с этим
Эдриан

3

Я НЕ хочу использовать ngAnimate на себе ng-if, так что это было бы моим решением:

[ng-if] {
  .ng-enter, .ng-leave, .ng-animate {
    -webkit-transition: none !important;
    transition: none !important;
  }
}

Просто разместите это как еще одно предложение!


2

У меня есть список, из которого первый liскрыт с помощью ng-hide="$first". Использование ng-enterрезультатов в том, liчто отображается полсекунды перед исчезновением.

Основываясь на решении Криса Барра, мой код теперь выглядит так:

HTML

<ol>
    <li ng-repeat="item in items"
        ng-hide="$first"
        ng-class="{'no-animate' : $first}">
    </li>
</ol>

CSS

.no-animate.ng-enter,
.no-animate.ng-leave,
.no-animate.ng-animate {
        transition: none !important; /* disable transitions */
        animation: none 0s !important; /* disable keyframe animations */
}

li.ng-enter {
    opacity: 0;
    transition: opacity 0.3s ease-out;
}
li.ng-enter-active {
    opacity: 1;
}

/* I use Autoprefixer. If you don't, please include vendor prefixes. */

0

Я знаю, что это отложенный ответ, но здесь мы используем в MainController:

// disable all animations
$animate.enabled(false);

Но проблема в том, что когда мы отключаем все анимации, ui-select настраивается на opacity: 0.

Итак, необходимо установить непрозрачность на 1 с помощью CSS:

.ui-select-choices {
    opacity: 1 !important;
}

Это правильно установит непрозрачность, и пользовательский интерфейс будет работать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.