Angular 1.x ngAnimate в Shadow DOM не регистрирует время анимации или добавляет классы ввода/отпуска

Я пытаюсь выработать решения в течение нескольких часов - все дубликаты в SO, похоже, не работают для меня, поскольку они в большинстве своем рекомендуют либо попробовать разные версии ng-animate/ angular или добавление перехода/анимации в соответствующие классы, чтобы ngAnimate мог правильно обрабатывать свои тайминги.

Моя проблема в том, что все это работало, и у меня были все свойства в правильных местах, но теперь я переношу расширение Chrome для работы в инкапсуляции Shadow DOM.

Примечания:

  • Тень DOM, вероятно, является виновником, но я не уверен, почему и как ее исправить. Это также может быть неактуальным или играть лишь незначительную роль в реальной проблеме (вероятно, это связано с плохой обработкой DOM в Shadow DOM + angular)
  • Я загружаю свое приложение вручную позже в жизненном цикле расширения, так как он должен запускаться только после обратного вызова. Это может быть и виновником

Вот plunker - Я думаю, что у меня случай изолирован как можно больше. Нажатие на ссылки должно открывать/закрывать divs после них в анимации скольжения вниз/вверх соответственно. В настоящее время они сразу открываются.

Вот соответствующие стили:

.view-container {
  position: absolute;
  top: 70px;
  bottom: 0;
  background: white;
  transition: all 0.4s 0.2s ease-in-out;
  overflow-y: hidden;
  // slide animation
  &,
  &.ng-hide-remove,
  &.ng-hide-remove-active {
    max-height: 500px;
  }

  &.ng-hide {
    max-height: 0;
  }
}

Вот шаблон:

<div ng-show="rchCtrl.view == 'flag'"
  class="view-container">
  <div ng-include="'/templates/extension/article-flag-form.html'"
    ng-if="rchCtrl.view == 'flag'"
    ng-controller="ArticleFlagCtrl as flg"
    class="article-flag"></div>
</div>

Файл Bower:

"dependencies": {
    "jquery": "^2.2.1",
    "trackjs": "^2.8.3",
    "angular": "^1.6.0",
    "qtip2": "^2.2.1",
    "ng-qtip2": "1.3.3",
    "angular-ui-router": "^0.2.18",
    "angular-cookies": "^1.6.0",
    "angular-resource": "^1.6.0",
    "bootstrap": "^3.3.7",
    "angular-animate": "^1.6.0"
  },
  "resolutions": {
    "angular": "1.6.6"
  }

Мой раздел angular init:

app = angular.module(APP_NAME, ['template-cache', 'ui.router', 'ngCookies', 'geCommon', 'ngAnimate'])

// ...

angular.bootstrap(shadow.querySelector('#ge-ext'), [ APP_NAME ], { debugInfoEnabled: true })
angular.resumeBootstrap()

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

Ответы

Ответ 1

Взгляните, если это то, чего вы пытаетесь достичь:

https://plnkr.co/edit/0rmEfPlsn3GsK6rtLalP?p=preview

Я сделал некоторые настройки в menu.html и style.css. В основном, то, что я сделал, это удалить из элементов, которые должны были иметь анимацию, такие как ng-hide/ng-show, и вместо этого я поместил ng-class, чтобы манипулировать видимость при сохранении анимации. Причина, по которой ng-hide/ng-show - не лучшие идеи для анимации, заключается в том, что они применяют свойство display: block к вашему элементу, поэтому любой применяемый к ним переход не будет работать. visiblity: visible/hidden - это ключ, если вы хотите использовать css-переходы.

// New styles
#menu li {
  transition: all 0.4s ease-in-out;
}

#menu li.invisible {
  height: 0;
  opacity: 0;
  visibility: hidden;
}

.article-feedback,
.article-flag {
  /* Zero height in normal start */
  height: 0;
  transition: all 0.4s ease-in-out;
}

.article-feedback.visible,
.article-flag.visible {
  /* When visible, height goes to 100px */
  height: 100px;
}
<ul id="menu"
  class="list-unstyled"
  ng-class="{'view-open': rchCtrl.view != null}"
  ng-show="rchCtrl.menuOpen"
  ng-controller="RelatedResearchesCtrl as rchCtrl">
  <li ng-class="{'invisible': rchCtrl.view && rchCtrl.view != 'feedback'}">
    <a fake-click
      ng-click="rchCtrl.openView('feedback')">
      Send feedback &amp; ideas
    </a>
    <span class="icon-close"
      ng-show="rchCtrl.view == 'feedback'"
      ng-click="rchCtrl.openView(null); $event.stopPropagation()">
      &times;
    </span>

    <!-- I've removed the ng-show and added ng-class, so transitions will work -->
    <div class="view-container">
      <div style="background: red;"
        ng-class="{'visible': rchCtrl.view == 'feedback'}"
        class="article-feedback"></div>
    </div>
  </li>
  <li ng-class="{'invisible': rchCtrl.view && rchCtrl.view != 'flag'}">
    <a fake-click
      ng-click="rchCtrl.openView('flag')">
      Flag this page
    </a>
    <span class="icon-close"
      ng-show="rchCtrl.view == 'flag'"
      ng-click="rchCtrl.openView(null); $event.stopPropagation()">
      &times;
    </span>
    <div class="view-container">

      <!-- I've removed the ng-show and added ng-class, so transitions will work -->
      <div style="background: blue;"
        ng-class="{'visible': rchCtrl.view == 'flag'}"
        class="article-flag"></div>
    </div>
  </li>
</ul>

Сообщите мне, есть ли какие-либо другие вопросы о моем plnkr.

Ответ 2

Я думаю, что вам не хватает этого из части css:

.ng-hide:not(.ng-hide-animate) {
  /* These are just alternative ways of hiding an element */
  display: block!important;
  position: absolute;
  top: -9999px;
  left: -9999px;
}

как упоминалось здесь и в Bruno Poeta.