暂停/播放每个子元素的所有CSS动画

时间:2017-11-07 14:20:17

标签: css animation css-animations

我正在创建一个充满CSS动画的仪表板页面。从Bootstrap的东西(动画进度条)到自定义动画。

当您单击某些元素时,会触发一个接近全屏的模式,这会与所有动画重叠,所以我想暂时将它们全部暂停(因为可能存在性能问题),方法是添加/删除一个类顶级元素,并在设置该类时使用CSS暂停所有动画。

这个解决方案只使用一行js,只是在打开模态时切换类。

我的模板看起来有点像这样:

<body>
    <div class="modal">
        <!-- Modal code -->
    </div>
    <div class="app">
        <!-- Template -->
    </div>
</div>

是否可以向.app添加一个类,该类会暂停每个子元素中的每个CSS动画?

注1:

我知道你可以使用我要求的完全相反的东西:即,对一个顶部元素设置一个默认的.animation-play类,并使用一个动画为每个子元素添加前缀这个类,然后删除这个类来暂停每个动画。就像:

app.animation-play .somediv .somediv .element {
    // animation code
}
app.animation-play .somediv .element {
    // animation code
}
app.animation-play .somediv .somediv .somediv .somediv .element {
    // animation code
}

但是我必须编辑CSS代码的 lot ,它看起来也不是很好。

注2:

我也对JS解决方案持开放态度,但我 更喜欢纯粹的CSS方式来实现这一目标。

2 个答案:

答案 0 :(得分:2)

当一个“暂停”类添加到您的应用包装器时,您可以使用通用选择器来定位所有内容,但是由于性能影响,许多CSS链接器仍然警告不要使用这些。

说实话,这些天的影响可能很小,例如许多CSS重置使用它们。

您可以使用以下内容:

.app.paused * { 
    animation: none; 
}

修改

通过上面的评论,似乎上面的选择器没有足够的优先权来覆盖动画,因此添加了“!important”。

.app.paused * { 
    animation: none !important;
    transition: none !important; 
}

然而,这通常不是一个好主意,我总是尽量避免不惜一切代价使用'!important',因为这些选择器的维护样式很困难。如果你可以用更高的优先级覆盖动画,那么最好这样做而不是使用'!important'。

编辑2:

正如您所提到的,您对JS解决方案持开放态度,这里有一些JS应该清除给定选择器中的所有动画。我不确定这样做的性能影响是什么,但我在这里添加它以防万一其他人更喜欢只使用JS来做它:

let stopAnimationsWrap = document.querySelector('.app');
let stoppedAnims = [];

// Stop animations
document.querySelector('.stop').addEventListener('click', () => {
  let appAllEls = stopAnimationsWrap.querySelectorAll('*');
  let allElsAr = Array.prototype.slice.call(appAllEls);

  allElsAr.forEach((thisEl) => {
    let elClass = thisEl.classList[0];
        let cs = getComputedStyle(thisEl, null);
    let thisAnimation = cs.getPropertyValue('animation-name');

    if (thisAnimation !== 'none') {

      stoppedAnims.push([elClass, {
        'animationName': thisAnimation
      }]);

      thisEl.style.animationName = 'none';
    }
  });
});

// Start animations
document.querySelector('.start').addEventListener('click', () => {

  stoppedAnims.forEach((thisEl) => {
    let domEl = '.' + thisEl[0];

    stopAnimationsWrap.querySelector(domEl).style.animationName = thisEl[1].animationName;
  });
});

<强>小提琴:

https://jsfiddle.net/vu6javb2/14/

答案 1 :(得分:-2)

.app {
    -webkit-animation-play-state: paused; /* Safari 4.0 - 8.0 */
    animation-play-state: paused;
}

悬停时:

.app:hover {
    -webkit-animation-play-state: paused; /* Safari 4.0 - 8.0 */
    animation-play-state: paused;
}