Set CSS animation delay with javascript

12,965

I've only tested this on Mac 10.8 Chrome 25, Safari 6.0, and FF 18.0.

Sounds like the main thing you wanted to do was add the data-delay value to whatever existing animation delay was applied to the elements.

HTML - unchanged

<div id="wrapper" data-delay="5.1s" >
    <h1 id="hi">Hi</h1>
    <h1 id="name">test!</h1>
</div>

CSS - Vendor prefixes and initial keyframes (0%) were added.

body { font-size: 300%; }

#wrapper h1 { position: absolute; }

#hi { 
    -webkit-transform: translate(-200px, 100px);
    -webkit-animation-name: hi;
    -webkit-animation-duration: .5s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-fill-mode: forwards;
    -webkit-animation-delay: 2.1s;

    -moz-transform: translate(-200px, 100px);
    -moz-animation-name: hi;
    -moz-animation-duration: .5s;
    -moz-animation-timing-function: linear;
    -moz-animation-fill-mode: forwards;
    -moz-animation-delay: 2.1s;

    transform: translate(-200px, 100px);
    animation-name: hi;
    animation-duration: .5s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: 2.1s;
}

#name { 
    -webkit-transform: translate(-200px, 150px);
    -webkit-animation-name: name;
    -webkit-animation-duration: .5s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-fill-mode: forwards;
    -webkit-animation-delay: 3.1s;

    -moz-transform: translate(-200px, 150px);
    -moz-animation-name: name;
    -moz-animation-duration: .5s;
    -moz-animation-timing-function: linear;
    -moz-animation-fill-mode: forwards;
    -moz-animation-delay: 3.1s;

    transform: translate(-200px, 150px);
    animation-name: name;
    animation-duration: .5s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    animation-delay: 3.1s;
}

@-moz-keyframes hi{
    0% { -moz-transform: translate(-200px, 100px); }
    100% { -moz-transform: translate(50px, 100px); }
}
@-webkit-keyframes hi {
    0% { -webkit-transform: translate(-200px, 100px); }
    100% { -webkit-transform: translate(50px, 100px); }
}
@keyframes hi{
    0% { transform: translate(-200px, 100px); }
    100% { transform: translate(50px, 100px); }
}

@-moz-keyframes name {
    0% { -moz-transform: translate(-200px, 150px); }
    100% { -moz-transform: translate(50px, 150px); }
}
@-webkit-keyframes name {
    0% { -webkit-transform: translate(-200px, 150px); }
    100% { -webkit-transform: translate(50px, 150px); }
}
@keyframes name {
    0% { transform: translate(-200px, 150px); }
    100% { transform: translate(50px, 150px); }
}

JAVASCRIPT

On an element, the style property doesn't hold all the style information because it only represents what is being set directly on the element via the style attribute. MDN

window.getComputedStyle() seems to work pretty well.

Juggling the prefixed properties is a little clunky, but it worked in the browsers I tested with.

(function(undefined) {

    var wrapper = document.getElementById('wrapper'),
        elms = wrapper.children,
        delay = wrapper.getAttribute('data-delay'),
        prop,
        styl,
        cur,
        i;

    delay = !delay ? 0 : Number(delay.replace(/[^\d\.]/g, ''));

    if (!elms.length) {
        return;
    }

    styl = window.getComputedStyle(elms[0]);

    if (styl.getPropertyValue('animation-delay')) {
        prop = 'animation-delay';

    } else if (styl.getPropertyValue('-webkit-animation-delay')) {
        prop = '-webkit-animation-delay';

    } else if (styl.getPropertyValue('-moz-animation-delay')) {
        prop = '-moz-animation-delay';

    } else {
        console.log('unable to find prop');
        return;
    }
    // console.log('prop', prop);

    for (i = 0; i < elms.length; i++) {
        styl = window.getComputedStyle(elms[i]);
        cur = styl.getPropertyValue(prop);
        cur = Number(cur.replace(/[^\d\.]/g, ''));
        elms[i].style.setProperty(prop, (cur + delay) + 's');

        console.log('delay: ' + cur + 's -> ' + (cur + delay) + 's')
    }

})();

http://jsfiddle.net/FHuKN/11/

Share:
12,965
tryzor
Author by

tryzor

Updated on June 17, 2022

Comments

  • tryzor
    tryzor almost 2 years

    I have some keyframe animations in my css file. There is already an animation-delay specified. The wrapper div has the attribute data-delay.

    I want to get the animation-delay in the css file and add the value of data-delay to it. Then i want that the animation start with the new delay.

    I tried ele[i].style.animationDelay. But it seems that this returns null until I set a value to it.

    If I set ele[i].style.animationDelay = '5s' the animation still runs with the delay of the css file.

    HTML

    <div id="wrapper" data-delay="2s" >
        <h1 id="hi">Hi</h1>
        <h1 id="name">test!</h1>
    </div>
    

    CSS

    body { font-size: 300%; }
    
    #wrapper h1 { position: absolute; }
    
    #hi {
        transform: translate(-200px, 100px);
    
        animation-name: hi;
        animation-duration: .5s;
        animation-timing-function: linear;
        animation-fill-mode: forwards;
        animation-delay: 0s;
    }
    
    #name {
        transform: translate(-200px, 150px);
    
        animation-name: name;
        animation-duration: .5s;
        animation-timing-function: linear;
        animation-fill-mode: forwards;
        animation-delay: 1s;
    }
    
    @keyframes hi{
        100% { transform: translate(50px, 100px) };
    }
    
    @keyframes name{
        100% { transform: translate(50px, 150px) };
    }
    

    JS

    var wrapper = document.getElementById('wrapper');
    var ele = wrapper.children;
    var delay = wrapper.getAttribute('data-delay');
    
    for (var i=0;i<ele.length;i++) {
    
        alert(ele[i].style.animationDelay);
        ele[i].style.animationDelay = delay;
        alert(ele[i].style.animationDelay);
    }
    

    http://jsfiddle.net/FHuKN/4/