Shadow DOM 中的 Angular 1.x ngAnimate 不注册动画时间或添加进入/离开类

Posted

技术标签:

【中文标题】Shadow DOM 中的 Angular 1.x ngAnimate 不注册动画时间或添加进入/离开类【英文标题】:Angular 1.x ngAnimate in Shadow DOM doesn't register animation times or add enter/leave classes 【发布时间】:2018-02-01 02:42:06 【问题描述】:

我已经尝试制定解决方案几个小时了 - SO 中的所有重复项似乎都不适合我,因为他们大多建议尝试不同版本的 ng-animate /angular 或在相关类中添加过渡/动画,以便 ngAnimate 可以正确处理它们的时间。

我的问题是所有这些都正常工作,并且我在正确的位置拥有所有属性 - 但现在我正在迁移我们的 Chrome 扩展程序以在 Shadow DOM 封装下工作。

注意事项:

Shadow DOM 可能是罪魁祸首,但我不确定为什么或如何修复它。它也可能无关紧要或仅在实际问题中起很小的作用(可能是由于 Shadow DOM + angular 中的不良 DOM 处理) 我在扩展注入生命周期的后期手动引导我的应用程序,因为它应该只在回调后启动。这也可能是罪魁祸首

这是plunker - 我想我已经尽可能地隔离了这个案例。单击链接应分别在向下/向上滑动动画中打开/关闭 div。目前他们只是立即开放。

以下是相关样式:

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

鲍尔文件:

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

我的角度初始化部分:

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

// ...

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

但在这一切之后,中间类永远不会添加/删除,并且动画不起作用 - 隐藏/显示显示是立即的。

【问题讨论】:

您想添加 jsfiddle 还是 sn-p 以获得更多帮助? @artgb 这是一个 plunker:plnkr.co/edit/yvtbBfVHZVRvihAGwr5M?p=preview,它重现了这个问题,希望不是因为我忘记从我的实际代码中复制一些东西。单击链接应分别在向下/向上滑动动画中打开/关闭 div。目前它立即显示 【参考方案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 有任何其他问题,请告诉我。

【讨论】:

嗯,我知道这种方法,我只是希望能解决实际问题,如果可以的话。这可能是我将随着任务时间的推移而去的。谢谢!在接受/奖励之前,我会等待看看其他人是否有任何想法 然而,这里的实际问题是 ng-hide-activeng-hide-active-remove 类从未应用。【参考方案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;

如here 和Bruno Poeta 回答中所述。

【讨论】:

以上是关于Shadow DOM 中的 Angular 1.x ngAnimate 不注册动画时间或添加进入/离开类的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Shadow DOM 中获得一个按钮来提交不在 Shadow DOM 中的表单吗?

shadow-dom浅析

shadow-dom 浅析

神秘的 shadow-dom 浅析

Shadow DOM 是不是像 React.js 中的 Virtual DOM 一样快?

Shadow dom 中的 FontAwesome svg