小编典典

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

css

我一直认为CSS3动画(与CSS3 Transitions不同) 一旦启动,就总是完成工作 ,无论选择器是否与激活它们的元素都不匹配。

我今天意识到自己可能是错的。

在以下示例中,动画由: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;
    

    }

    Lorem

    Ipsum

    dolor

    sit

    amet

    consectetur

    adipiscing

    elit

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

    a { transition: all 2s ease; }

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

-我也知道我可以使用jQuery动画代替CSS3动画,并使它那样工作; 编辑
:根据评论,如果我没看错的话,甚至连jQuery动画都不会以这种方式工作)

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

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


阅读 279

收藏
2020-05-16

共1个答案

小编典典

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

实现此目的的唯一方法是使用脚本。以下是使用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');

  }

}


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

animationcancel注释中提到的事件(由BoltClock提出)对于我们的案例可能更有用,但它只是遇到动画异常结束时触发的事件。我们仍然必须编写自己的代码,以使其继续到周期结束。

2020-05-16