伪元素并听取过渡到结束

时间:2015-04-21 14:40:32

标签: jquery css3

我有一个导航,其中伪元素为图标(a:之前)。

<ul>
  <li><a href="#">click me</a></li>
  <li><a href="#">click me</a></li>
</ul>
<style>
  /* that's a placeholder for the icon */
  a:before {
    content : 'X';
    width:1em;height:1em;line-height:1em;font-size:1em;
    border-radius : 50%; background-color : blue;
  }
</style>

如果我点击一个锚,我希望这个图标旋转。我是通过jQuery .on('click')并添加具有CSS-Transition的类来实现的。这很好用。

看看这个小提琴,这很简单:

  

https://jsfiddle.net/14yet0ts/1/

...

问题

但是,经过很短的时间(我在我的jsFiddle中使用setTimeout()来模拟ajax请求),我希望CSS-Transition在完成后结束。

我已经看到,有jQuery可以监听的transitionend-events,但我不能听,因为转换是在标签的伪元素上设置的,不能通过DOM访问。

是否有可能在不更改HTML的情况下收听转换结束?

主要是脚本的这部分不起作用:

$('a:before', el).one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
    alert('2: transition ended, remove class loading');
    el.removeClass('loading');
}); 

干杯

3 个答案:

答案 0 :(得分:2)

首先,您没有使用过渡,而是使用动画。因此,您需要使用与动画相关的事件。在这种情况下,您需要animationiteration

最后,您无法在伪元素本身上监听事件。但是,事件会冒泡到a,因此您可以在那里收听:

function removeTransition(el) {
    //  this does not work!
    $('a', el).one('animationiteration webkitAnimationIteration oanimationiteration MSAnimationIteration', function(){
        el.removeClass('loading');
    });    
}

您还需要删除提醒,因为它们会阻止平稳过渡

https://jsfiddle.net/14yet0ts/3/


与提出的确切问题无关的另一个注意事项,您应该更新您的代码,以便仅从点击的li中移除该类,否则如果同时出现多个动画,则会出现问题。

$('a').on('click', function(e) {
    var wait = 1000 + Math.floor(Math.random()*2)*1000;

    // el is the exact `li`, not all loading `li` elements
    var el = $(this).closest('li').addClass('loading');
    e.preventDefault();

    setTimeout(function() {
        removeTransition(el);
    }, wait);
});

https://jsfiddle.net/14yet0ts/4/

答案 1 :(得分:0)

您可以使用:focus CSS伪选择器,完全不需要jQuery。

&#13;
&#13;
 /* that's a placeholder for the icon */
 a:before {
   content: 'X';
   width: 1em;
   height: 1em;
   line-height: 1em;
   font-size: 1em;
   border-radius: 50%;
   background-color: blue;
 }
 a:focus:before {
   -webkit-transform: rotate(360deg);
   -moz-transform: rotate(360deg);
   transform: rotate(360deg);
   transition: all 0.4s;
 }
&#13;
<ul>
  <li><a href="#">click me</a>
  </li>
  <li><a href="#">click me</a>
  </li>
</ul>
&#13;
&#13;
&#13;


另一种方法是使用动画关键帧:

&#13;
&#13;
/* that's a placeholder for the icon */

a:before {
  content: 'X';
  width: 1em;
  height: 1em;
  line-height: 1em;
  font-size: 1em;
  border-radius: 50%;
  background-color: blue;
}
a:focus:before {
  -webkit-animation: 4s rotateMe linear forwards;
  animation: 4s rotateMe linear forwards;
}
@-webkit-keyframes rotateMe {
  from {
    -webkit-transform: rotate(0);
    transform: rotate(0);
  }
  to {
    -webkkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes rotateMe {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(360deg);
  }
}
&#13;
<ul>
  <li><a href="#">click me</a>
  </li>
  <li><a href="#">click me</a>
  </li>
</ul>
&#13;
&#13;
&#13;


根据您的评论

为了生成此随机超时&#39;,我会使用一个类切换。

然而,这仍然不允许顺利完成&#39;在停止之前

换句话说,比如:

&#13;
&#13;
$(document).ready(function(){
  $('a').click(function() {
    $(this).addClass("myClass");

  });
  $('#stop').click(function(){
    $('a').removeClass("myClass")
    });

});
&#13;
/* that's a placeholder for the icon */

a:before {
  content: 'X';
  width: 1em;
  height: 1em;
  line-height: 1em;
  font-size: 1em;
  border-radius: 50%;
  background-color: blue;
}

.myClass:before {
  -webkit-animation: 4s rotateMe linear  infinite;
  animation: 4s rotateMe linear  infinite;
}
@-webkit-keyframes rotateMe {
  from {
    -webkit-transform: rotate(0);
    transform: rotate(0);
  }
  to {
    -webkkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes rotateMe {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(360deg);
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li><a href="#">click me</a>
  </li>
  <li><a href="#">click me</a>
  </li>
</ul>

<button id="stop">button to play the 'stop' action</button>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

&#13;
&#13;
	$('a').on('click', function(e) {
    var wait = 1000 + Math.floor(Math.random()*2)*1000;
    $(this).closest('li').addClass('loading');
    e.preventDefault();
    
    setTimeout(function() {
        var el = $('li.loading');
        alert('1: wait countdown ended, start listening to transition to end one last time');
        removeTransition(el);
    }, wait);
});

function removeTransition(el) {
    //  this does not work!   
        alert('2: transition ended, remove class loading');
        el.removeClass('loading');

}
&#13;
/* global */
ul,li{list-style-type:none;margin:15px;}

/* anchor */
a:before {
    content : 'X';
    display : block;
    background-color : red;
    color : white;
    width:1em;height:1em;line-height:1em;font-size:1em;
    border-radius : 50%;
    float:left;text-align:Center;
}

/* loading animation */
li.loading a {
    color : green;
    text-decoration : none;
}
li.loading > a:before {
    -webkit-animation-name : rotate;
    -webkit-animation-duration : 2s;
    -webkit-animation-iteration-count : infinite;
    -webkit-animation-timing-function : linear;
    -moz-animation-name : rotate;
    -moz-animation-duration : 2s;
    -moz-animation-iteration-count : infinite;
    -moz-animation-timing-function : linear;
}
@-webkit-keyframes rotate {
    from {-webkit-transform : rotate(0deg);}
    to {  -webkit-transform : rotate(360deg);}
}
@-moz-keyframes rotate {
    from {-moz-transform : rotate(0deg);}
    to {  -moz-transform : rotate(360deg);}
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
    <ul>
        <li>
            <a href="#">click me</a>
        </li>
        <li>
            <a href="#">click me</a>
        </li>
        <li>
            <a href="#">click me</a>
        </li>
    </ul>
</nav>
&#13;
&#13;
&#13;

如果我将javascript修改为此,这对我来说很好......

function removeTransition(el) { 
        alert('2: transition ended, remove class loading');
        el.removeClass('loading');

}