【问题标题】:How to run the CSS3 animation to the end if the selector is not matching anymore?如果选择器不再匹配,如何将 CSS3 动画运行到最后?
【发布时间】:2015-10-26 16:51:58
【问题描述】:

我一直认为 CSS3 动画(不同于 CSS3 过渡)一旦开始,总是完成工作,无论选择器是否不再匹配激活它们的元素。

我今天意识到我可能错了。

在以下示例中,动画由 :focus:active 伪类触发。 关注第一个文本字段:

  • 如果你慢慢按下tab按钮,你会看到动画正确开始和结束;
  • 如果你快速按下tab按钮,你会看到一旦新元素获得焦点,旧元素的动画立即结束并消失。

@-webkit-keyframes pressed {    
    0%, 100% { transform : scale(1); }
         50% { transform : scale(2); }
}
@keyframes pressed {    
    0%, 100% { transform : scale(1); }
         50% { transform : scale(2); }
}
a:focus, a:active {
    -webkit-animation : pressed 2s; 
            animation : pressed 2s; 
}

a, input {
          border : 1px solid silver; 
         padding : 5px;
          height : 40px;
     line-height : 28px;
          margin : 0px;
         display : inline-block;
           width : 33.3%;
      box-sizing : border-box;  
      background : white; 
  vertical-align : middle;
}

a { 
           color : dodgerBlue; 
 text-decoration : none;}

input {
           color : red;
}
<input type="text" id="foo" value="Start here, then press tab" /><a  href = "#">
Lorem
</a><a  href = "#">
Ipsum
</a><a  href = "#">
dolor
</a><a  href = "#">
sit
</a><a  href = "#">
amet
</a><a  href = "#">
consectetur 
</a><a  href = "#">
adipiscing 
</a><a  href = "#">
elit
</a>

我知道我可以通过以下应用使其顺利结束(在某些浏览器上,例如 Firefox 是,Chrome 否):

    a { transition: all 2s ease; }

因此,如果它加载到(例如)40%,它会从 40% 动画回到 0%,而不是立即下降到 0%。

- 我也知道我可以使用 jQuery 动画而不是 CSS3 动画并让它以这种方式工作; 编辑:根据评论,如果我没看错的话,即使是 jQuery 动画也不会这样工作)

作为一名 CSS3 动画新手,我在这里要问的是:

是否有一种纯 CSS3 方式可以强制动画运行到 100%,无论初始条件是否不再有效?

【问题讨论】:

  • 看起来不像。甚至 Animations level 2 也只是为此提供了一个 DOM 事件,这意味着您现在甚至无法通过脚本控制它,直到实现 animationcancel
  • 不完全相关,但您能否使用transition 顺利地将其动画化?我以前从未见过这种情况,我的 sn-p 不会发生这种情况(在 Chrome v38 中)。
  • @BoltClock:所以答案是 “不,即使使用 jQuery” ?我还没有尝试过,只是假设通过编写脚本它会起作用。好吧,我想我会用一些 JS 魔法来解决问题,然后:/ 谢谢,随时添加它作为答案。
  • @Harry:你说得对,它在 Firefox 上完美运行,但在 Chrome 上却无法运行(无论是动画还是 -webkit-animation...):|
  • @Harry 是的,这就是我做这类事情的方式,例如。在需要时用于 IE 的逆向兼容性(不过通常使用 jQuery)。随意将其添加为答案,我总是支持每个(有用的)答案。 PS:我也不是移动开发专家...实际上,我什至不是前端开发人员:DI 就像照顾这部分一样,特别是因为我们超级昂贵的前端人员甚至更多比我马虎:|所以我要全栈广度优先

标签: html css css-selectors css-animations


【解决方案1】:

正如在 cmets 中所讨论的,即使在最初应用动画的选择器规则不再适用之后,目前也无法强制动画完成一个完整的周期。

实现此目的的唯一方法是使用脚本。下面是一个使用 JavaScript 的示例 sn-p。它的作用是在元素获得焦点时向元素添加一个类(具有animation 属性集),然后仅在动画结束时将其移除。

注意:我在 sn-p 中使用了 webkitAnimationEnd 事件,所以它在其他浏览器中不起作用。该代码还需要更多微调,因为它目前仅在动画结束时删除该类。因此,如果您在一个周期完成之前退出并加入标签,则不会发生任何事情。

window.onload = function() {
  var anchors = document.querySelectorAll('a');
  for (var i = 0; i < anchors.length; i++) {
    anchors[i].addEventListener('focus', function() {
      addanim(this);
    });
    anchors[i].addEventListener('webkitAnimationEnd', function() {
      endanim(this);
    });
  }

  function addanim(el) {
    el.classList.add('focus');
  }

  function endanim(el) {
    el.classList.remove('focus');
  }
}
@keyframes pressed {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(2);
  }
}
.focus {
  animation: pressed 2s;
}
a,
input {
  border: 1px solid silver;
  padding: 5px;
  height: 40px;
  line-height: 28px;
  margin: 0px;
  display: inline-block;
  width: 33.3%;
  box-sizing: border-box;
  background: white;
}
a {
  color: dodgerBlue;
  text-decoration: none;
}
input {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>

<input type="text" id="foo" value="Start here, then press tab" />
<a href="#">Lorem</a>
<a href="#">Ipsum</a>
<a href="#">dolor</a>
<a href="#">sit</a>
<a href="#">amet</a>
<a href="#">consectetur</a>
<a href="#">adipiscing</a>
<a href="#">elit</a>

cmets 中提到的animationcancel 事件(由 BoltClock 提供)可能对我们的案例更有用,但它只是在遇到动画异常结束时触发的事件。我们仍然需要编写自己的代码以使其持续到循环结束。

【讨论】:

    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多