如果选择器不再匹配,如何将CSS3动画运行到最后?

And*_*ios 6 html css css-selectors css3 css-animations

我一直认为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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过以下方式顺利结束(在某些浏览器上,例如Firefox是,Chrome no)

    a { transition: all 2s ease; }
Run Code Online (Sandbox Code Playgroud)

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

- 我也知道我可以使用jQuery动画而不是CSS3动画,并使其以这种方式工作; (编辑:根据评论,即使jQuery动画也会以这种方式工作,如果我做对了)

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

是否有纯CSS3方式强制动画运行高达100%,无论初始条件是否无效?

Har*_*rry 2

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

实现这一目标的唯一方法是使用脚本。下面是使用 JavaScript 的示例片段。其作用是animation在元素获得焦点时向元素添加一个类(已设置属性),然后仅在动画结束时将其删除。

注意: 我在代码片段中使用了 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');
  }
}
Run Code Online (Sandbox Code Playgroud)
@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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

注释中提到的事件animationcancel(由 BoltClock 提供)对于我们的情况可能更有用,但它只是在遇到动画异常结束时触发的事件。我们仍然需要编写自己的代码以使其持续到一个周期结束。