在悬停时停止的处理栏循环

时间:2015-11-16 12:38:15

标签: javascript jquery css css3 css-animations

我想创建一个处理栏,当它增长到100%宽度时执行函数foo()

HTML:

<div></div>

CSS:

position: absolute;
top: 0px;
left: 0px;
height: 2px;
width: 0px;
background-color: rgba(0, 0, 0, 0.3);

所以我尝试用CSS动画做到这一点。

JS:

var duration = parseInt("15");
var bar = $("[...] div");
doSomething = (function () {
    bar.css({
        "animation-duration" : duration+"s",
        "animation-name" : "expand",
        "animation-timing-function" : "linear"
    });
    bar.on("animationend oAnimationEnd MSAnimationEnd mozAnimationEnd webkitAnimationEnd", function(e) {
        bar.css("animation-name", "none");
        foo();
        $(this).off(e);
    });
    doSomething();
});

这在第一次运行中完美运行,但它不会循环。

但是通过这个解决方案,我可以轻松地在hover添加一个停靠点:

CSS:

 animation-play-state: paused;

我尝试使用jQuery animate()的解决方案,循环有效,但我不知道如何在悬停时添加停止并暂停动画,因为jQuery中没有选项可以做这样的事情。当然我可以停止动画,但是当我再次运行时,它会以相同的持续时间播放宽度的其余部分。

JS:

doSomething = (function () {
    /* First try
    interval = setInterval(function(){
        bar.animate({
            width: "100%",
        }, duration, "linear", function() {
            bar.css("width", "0px");
            foo();
        });
    }, 0);*/
    bar.animate({
        width: "100%",
    }, duration, "linear", function() {
        bar.css("width", "0px");
        foo();
    });
});
$("[parent of bar]")
    .mouseenter(function() {
        bar.stop();
    })
    .mouseleave(function() {
        bar.finish(); /* Animate: 100% - currentWidth in duration */
    });

那么还有其他想法吗?

2 个答案:

答案 0 :(得分:2)

&#13;
&#13;
$(document).ready(function() {
            $('.childSpan').addClass('progress');
            $('.childSpan').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
                console.log('100%');//call the foo() function here
                $('.childSpan').removeClass('progress');
                setTimeout(function() {
                    $('.childSpan').addClass('progress');
                }, 1);
            });
        });
&#13;
@-webkit-keyframes progress {
    0%{width:0%;}
    50%{width:50%;}
    100%{width:100%;}	
}

@-moz-keyframes progress {
    0%{width:0%;}
    50%{width:50%;}
    100%{width:100%;}	
}

@-o-keyframes progress {
    0%{width:0%;}
    50%{width:50%;}
    100%{width:100%;}	

}

@keyframes progress {
    0%{width:0%;}
    50%{width:50%;}
    100%{width:100%;}	

} 
.progress {
    -webkit-animation-name: progress;
    -moz-animation-name: progress;
    -o-animation-name: progress;
    animation-name: progress;
    -webkit-animation: progress 2s  linear;
    -moz-animation: progress 2s  linear;
    -o-animation: progress 2s  linear;
    -ms-animation: progress 2s  linear;

}

.parentDiv:hover > .childSpan {
    -webkit-animation-play-state: paused;
    animation-play-state: paused;
}
.parentDiv{width:300px;background:black;height:50px;}
.childSpan{background: red none repeat scroll 0 0;display: block;height: 50px;width:0%;}
&#13;
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<div id="processDiv" class="parentDiv">
 <span id="process" class="childSpan">
	
 </span>
</div>
&#13;
&#13;
&#13;

试试这个,只需要在动画结束后添加和删除类。

如果您在完成后不需要该事件,那么其余的可以通过css完成,只需要将动画类型更改为

-webkit-animation: shake 2s infinite linear;
-moz-animation: shake 2s infinite linear;
-o-animation: shake 2s infinite linear;
-ms-animation: shake 2s infinite linear; 

默认情况下,在span上添加进度类,不需要任何jquery代码。

答案 1 :(得分:1)

在代码中,当animationend事件被触发时,您将取消或删除动画。因此,循环将不起作用。如果你想支持循环,那么你可以在处理doSomething函数结束时调用foo()来重新附加动画和事件处理程序。

在下面的代码片段中,foo()函数将在动画完成后显示“Animation Completed ..”文本,然后在2秒延迟后重新启动动画。

var duration = parseInt("15");
var bar = $("div.animated-element");
doSomething = (function() {
  bar.css({
    "animation-duration": duration + "s",
    "animation-name": "expand",
    "animation-timing-function": "linear"
  });
  bar.on("animationend oAnimationEnd MSAnimationEnd mozAnimationEnd webkitAnimationEnd", function(e) {
    bar.css("animation-name", "none");
    foo();
    $(this).off(e);
  });
});
doSomething();

function foo() {
  var op = $('div.output');
  op.html("Animation Completed....");
  window.setTimeout(function() {
    doSomething();
    op.html("");
  }, 2000);
}
div.animated-element {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 50px;
  width: 0px;
  background-color: rgba(0, 0, 0, 0.3);
}
@keyframes expand {
  from {
    width: 0px;
  }
  to {
    width: 200px;
  }
}
div.animated-element:hover {
  animation-play-state: paused !important; /* important is needed because of inline animation styles or you can set this also inline using jQuery*/
}

div.output{
  margin-top: 50px;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='animated-element'></div>
<div class='output'></div>

或者,您还可以animationiteration事件在动画的每次迭代结束时触发foo()函数,并在动画播放时使用animationend触发foo()一劳永逸地完成。

在下面的代码片段中,foo()函数将在动画的每次迭代后显示“动画已完成...”(误导文字,但是你得到了点)文本,在2秒延迟后文本会消失但是动画将继续运行,直到完成5次迭代。最后,经过5次迭代后,动画将停止。

var duration = parseInt("15");
var bar = $("div.animated-element");
doSomething = (function() {
  bar.css({
    "animation-duration": duration + "s",
    "animation-name": "expand",
    "animation-timing-function": "linear",
    "animation-iteration-count" : "5"
  });
  bar.on("animationend oAnimationEnd MSAnimationEnd mozAnimationEnd webkitAnimationEnd", function(e) {
    bar.css("animation-name", "none");
    foo();
    $(this).off(e);
  });
  bar.on("animationiteration oAnimationIteration MSAnimationIteration mozAnimationIteration webkitAnimationIteration", function(e) {
    foo();
  });  
});
doSomething();

function foo() {
  var op = $('div.output');
  op.html("Animation Completed....");
  window.setTimeout(function() {
    op.html("");
  }, 2000);
}
div.animated-element {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 50px;
  width: 0px;
  background-color: rgba(0, 0, 0, 0.3);
}
@keyframes expand {
  from {
    width: 0px;
  }
  to {
    width: 200px;
  }
}
div.animated-element:hover {
  animation-play-state: paused !important; /* important is needed because of inline animation styles or you can set this also inline using jQuery*/
}

div.output{
  margin-top: 50px;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='animated-element'></div>
<div class='output'></div>

您可以在spec here中详细了解各种动画相关事件