3

在查看这个问题Set Webkit Keyframes Values Using Javascript Variable 接受的答案是 Webkit 特定的动态更改关键帧 CSS 的方法时,我决定看看我是否可以更改它以便它可以在 Firefox 中工作。

我设法得到了这个工作正常的JSFiddle,除了有时动画无法启动的事实。大约 1/4 的点击会启动动画,但另外 3/4 的点击不会导致任何事情发生。

有人可以向我解释到底发生了什么吗?我是否错过了一些简单的事情,或者在某处我没有考虑到比赛条件?

HTML

<div id="box"></div>

<div id="update-box">Run Another Animation</div>

CSS

@-webkit-keyframes rotate {
    0% {-webkit-transform: rotate(-10deg);}
    100% {-webkit-transform: rotate(10deg);}
}
@keyframes rotate {
    0% {-moz-transform: rotate(-10deg);}
    100% {-moz-transform: rotate(-10deg);}
}
body { text-align: center; }
#box {
        height: 100px;
        width: 100px;
        background-color: blue;
        -webkit-animation-duration: 1s;
        -webkit-animation-timing-function: linear;
        -webkit-animation-name: "rotate";
        animation-duration: 1s;
        animation-timing-function: linear;
        animation-name: "rotate";
        margin: 30px auto;
}

#update-box {
    border: 3px solid black;
    background: #efefef;
    font-weight: bold;
    cursor: pointer;   
    padding: 10px;
    margin: 30px auto;
    display: inline-block;
}
#update-box:hover {
    background: black;
    color: white;
}

JS

// search the CSSOM for a specific -webkit-keyframe rule
function findKeyframesRule(rule) {
    // gather all stylesheets into an array
    var ss = document.styleSheets;

    // loop through the stylesheets
    for (var i = 0; i < ss.length; ++i) {

        // loop through all the rules
        for (var j = 0; j < ss[i].cssRules.length; ++j) {
            // find the -webkit-keyframe rule whose name matches our passed over parameter and return that rule
            if ((ss[i].cssRules[j].type == window.CSSRule.KEYFRAMES_RULE) && ss[i].cssRules[j].name == rule) return [ss[i], ss[i].cssRules[j]];
        }
    }

    // rule not found
    return null;
}

// remove old keyframes and add new ones
function change(anim) {
    // find our -webkit-keyframe rule
    var results = findKeyframesRule(anim);
    var style_sheet = results[0];
    var rule = results[1];
    console.log(rule)
    // remove the existing 0% and 100% rules
    rule.deleteRule("0%");
    rule.deleteRule("100%");
    rule.appendRule("0% { -moz-transform: rotate(0deg);}")
    rule.appendRule("100% { -moz-transform: rotate(" + randomFromTo(-360, 360) + "deg); }")

    // create new 0% and 100% rules with random numbers

    // assign the animation to our element (which will cause the animation to run)
    document.getElementById('box').style.animationName = anim;
}

// begin the new animation process
function startChange() {
    // remove the old animation from our object
    document.getElementById('box').style.animationName = "none";

    // call the change method, which will update the keyframe animation
    setTimeout(function () {
        change("rotate");
    }, 0);
}

// get a random number integer between two low/high extremes
function randomFromTo(from, to) {
    return Math.floor(Math.random() * (to - from + 1) + from);
}

$(function () {
    $('#update-box').bind('click', click_handler);
});

function click_handler(e) {
    e.preventDefault();
    startChange();
}
4

1 回答 1

2

原来是刷新问题

// search the CSSOM for a specific -webkit-keyframe rule
function findKeyframesRule(rule) {
    // gather all stylesheets into an array
    var ss = document.styleSheets;

    // loop through the stylesheets
    for (var i = 0; i < ss.length; ++i) {

        // loop through all the rules
        for (var j = 0; j < ss[i].cssRules.length; ++j) {
            // find the -webkit-keyframe rule whose name matches our passed over parameter and return that rule
            if ((ss[i].cssRules[j].type == window.CSSRule.KEYFRAMES_RULE) && ss[i].cssRules[j].name == rule) return [ss[i], ss[i].cssRules[j]];
        }
    }

    // rule not found
    return null;
}

// remove old keyframes and add new ones
function change(anim) {
    // find our -webkit-keyframe rule
    var results = findKeyframesRule(anim);
    var style_sheet = results[0];
    var rule = results[1];
    console.log(rule)
    // remove the existing 0% and 100% rules
    rule.deleteRule("0%");
    rule.deleteRule("100%");
    rule.appendRule("0% { transform: rotate(0deg);}")
    rule.appendRule("100% { transform: rotate(" + randomFromTo(-360, 360) + "deg); }")

    // create new 0% and 100% rules with random numbers
    var box = document.getElementById('box');
    // assign the animation to our element (which will cause the animation to run)
    box.style.animationName = 'none';
    box.offsetWidth = box.offsetWidth;
    box.style.animationName = anim;
}

// begin the new animation process
function startChange() {
    change("rotate");
}

// get a random number integer between two low/high extremes
function randomFromTo(from, to) {
    return Math.floor(Math.random() * (to - from + 1) + from);
}

$(function () {
    $('#update-box').bind('click', click_handler);
});

function click_handler(e) {
    e.preventDefault();
    startChange();
}

是更新的工作代码。

http://jsfiddle.net/RHhBz/675/

以下是重要的变化

box.style.animationName = 'none';
box.offsetWidth = box.offsetWidth; //This line here is needed to force refresh
box.style.animationName = anim;
于 2015-08-12T13:39:01.953 回答