简体   繁体   中英

Unable to change 'animation-duration' CSS on body with jQuery

I have a CSS animation running on the body element, which has a default duration of 20s. I want this to be able to be changed through user input, but I can't seem to get it working.

The default CSS I have is:

body {    
    ...    
    animation: MoveBG 20s ease infinite;
}

If I run this jQuery code:

$('body').css('animation', 'MoveBG 2s ease infinite');

The animation will still have a 20s duration. The funny thing is that if I run:

alert($('body').css('animation-duration'));

It will tell me that the animation duration is 2s (which it clearly isn't).

 // the animation duration should change to 2s, but it still animates at 20s var animation = 'MoveBG 2s ease infinite'; $('body').css('animation', animation); // it even says that it is animate at 2s //alert($('body').css('animation-duration')); 
 body { background: linear-gradient(to right, #f00, #0f0, #00f); background-size: 600% 100%; -webkit-animation: MoveBG 20s ease infinite; -moz-animation: MoveBG 20s ease infinite; -o-animation: MoveBG 20s ease infinite; animation: MoveBG 20s ease infinite; } @-webkit-keyframes MoveBG { 0% { background-position: 0 0 } 50% { background-position: 100% 0 } 100% { background-position: 0 0 } } @-moz-keyframes MoveBG { 0% { background-position: 0 0 } 50% { background-position: 100% 0 } 100% { background-position: 0 0 } } @-o-keyframes MoveBG { 0% { background-position: 0 0 } 50% { background-position: 100% 0 } 100% { background-position: 0 0 } } @keyframes MoveBG { 0% { background-position: 0 0 } 50% { background-position: 100% 0 } 100% { background-position: 0 0 } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

Jsfiddle: http://jsfiddle.net/sdobc5vx/2/

Can anybody see what I'm doing wrong?

This is happening to me in Chrome 37 - but it looks like it's working in Firefox 30. Hmm...

Not exactly sure, but it looks like the frame refresh is not happening even if you override the already started keyframe, possibly a chrome bug.

One trick is to hide and element and show it (asynchronously) for repaint to happen (But not so desirable with flicker).

   $('body').css('animation', animation).hide().show(0);
                                                   //^__ Need this to force asyncronous show

 var animation = 'MoveBG 2s ease infinite'; $('body').css('animation', animation).hide().show(0); //^___Asyncronously show 
 body { background: linear-gradient(to right, #f00, #0f0, #00f); background-size: 600% 100%; -webkit-animation: MoveBG 20s ease infinite; -moz-animation: MoveBG 20s ease infinite; -o-animation: MoveBG 20s ease infinite; animation: MoveBG 20s ease infinite; } @-webkit-keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } @-moz-keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } @-o-keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } @keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <body> </body> 

Here is another hack that works. Reset the animation to none and then set it back again, which really doesn't give a flicker.

var animation  = 'MoveBG 2s ease infinite';
var $body = $('body').css('animation', 'none'); //reset it
setTimeout(function(){
    $body.css('animation', animation); //set it back
});

Demo2

You could use the same hack with addClass as well.

Edit, Updated

Try (workaround)

var duration = "2s";
$("body")[0].style.WebkitAnimationDuration = duration;
$("style").detach().hide(function() {
  $("head").prepend(this);
});

 $(function() { var twenty = $(".twenty"); var two = $(".two"); var span = $("span"); span.prepend("<b>twenty: </b>" + window.getComputedStyle(twenty[0], null).WebkitAnimation + " <b>before</b>" + "<br><b>two: </b>" + window.getComputedStyle(two[0], null).WebkitAnimation + "<b> before</b>"); // the animation duration should change to 2s, but it still animates at 20s var duration = "2s"; // $('body').css('animation', animation); two[0].style.WebkitAnimationDuration = duration; $("style").detach().hide(function() { $("head").prepend(this); }); span.append("<br><b>twenty: </b>" + window.getComputedStyle(twenty[0], null).WebkitAnimation + " <b>after</b>" + "<br><b>two: </b>" + window.getComputedStyle(two[0], null).WebkitAnimation + "<b> after</b>"); // it even says that it is animate at 2s alert(two.css('animation-duration') + "\\n" + window.getComputedStyle(two[0], null).webkitAnimationDuration); }); 
 span { font-size : 12px; height : 50px !important; } div.two { margin-left:20px; } div { display : inline-block; position : relative; width : 200px; height : 400px; background: linear-gradient(to right, #f00, #0f0, #00f); background-size: 600% 100%; -webkit-animation: MoveBG 20s ease infinite; -moz-animation: MoveBG 20s ease infinite; -o-animation: MoveBG 20s ease infinite; animation: MoveBG 20s ease infinite; } @-webkit-keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } @-moz-keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } @-o-keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } @keyframes MoveBG { 0%{background-position:0 0} 50%{background-position:100% 0} 100%{background-position:0 0} } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <body> <span class="animations"></span><br /> <div class="twenty"></div><div class="two"></div> </body> 

jsfiddle http://jsfiddle.net/sdobc5vx/31/

I've tried it on Safari works just fine. Chrome is not responding to anything.

Try doing this, see if will make any difference:

 $('body').css({ -webkit-animation: animation, -moz-animation: animation, -o-animation: animation, animation: animation, }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM