为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 vanilla JS 中的元素中删除 CSS 动画

如何从 vanilla JS 中的元素中删除 CSS 动画

料青山看我应如是 2021-06-05 16:12:38
我有一个由 nxn 个较小的方形 div 元素组成的方形网格,我想用 CSS 背景颜色动画按顺序照亮这些元素。我有一个函数来为序列生成一个随机数组。我遇到的问题是,一旦某个方块被照亮一次,如果它再次出现在阵列中,它就不会第二次照亮。我相信这是因为一旦为元素分配了 CSS 动画,动画就无法在该元素上再次触发,而且我无法找到使其工作的方法。这是我正在学习的响应式 Web 应用程序课程,评估规定我们只能使用 vanilla JS,并且所有元素必须在 JS 中创建并附加到<body>我们的 index.html 中的空白处。根据序列的每个闪光都是通过 setTimeout 函数触发的,该函数循环遍历数组中的所有元素,每次循环将其计时器增加 1 秒(动画长度也是 1 秒)。定义容器和子 div:function createGameContainer(n, width, height) {    var container = document.createElement('div');    //CSS styling    container.style.margin = '50px auto'    container.style.width = width;    container.style.height = height;    container.style.display = 'grid';    // loop generates string to create necessary number of grid columns based on the width of the grid of squares    var columns = '';    for (i = 0; i < n; i++) {        columns += ' calc(' + container.style.width + '/' + n.toString() + ')'    }    container.style.gridTemplateColumns = columns;    container.style.gridRow = 'auto auto';    // gap variable to reduce column and row gap for larger grid sizes    // if n is ever set to less than 2, gap is hardcoded to 20 to avoid taking square root of 0 or a negative value    var gap;    if (n > 1) {        gap = 20/Math.sqrt(n-1);    } else {        gap = 20;    }    container.style.gridColumnGap = gap.toString() + 'px';    container.style.gridRowGap = gap.toString() + 'px';    container.setAttribute('id', 'game-container');    document.body.appendChild(container);}/*function to create individual squares to be appended to parent game container*/function createSquare(id) {    var square = document.createElement('div');    //CSS styling    square.style.backgroundColor = '#333';    //square.style.padding = '20px';    square.style.borderRadius = '5px';    square.style.display = 'flex';    square.style.alignItems = 'center';    //set class and square id    square.setAttribute('class', 'square');    square.setAttribute('id', id);    return square;}
查看完整描述

2 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

试试这个:


function flash(index, delay){

    setTimeout( function() {

        flashingSquare = document.getElementById(index);

        flashingSquare.classList.add('flashing');

        flashingSquare.addEventListener('animationend', function() {

                flashingSquare.classList.remove('flashing');

        }, delay);    

    });

}

不要删除动画,删除 class。


动画完成后直接删除类。所以浏览器有时间处理所有事情。当您在需要动画之前直接添加类时,浏览器可以触发所有需要的步骤来执行此操作。


您删除和添加课程的尝试很好,但速度很快。我认为浏览器和 DOM 优化了你的步骤并且什么都不做。


查看完整回答
反对 回复 2021-06-11
?
温温酱

TA贡献1752条经验 获得超4个赞

经过一番研究,我想出了一个解决方法。我重写了函数,以便 setTimeout 嵌套在 for 循环中,setTimeout 嵌套在立即调用的函数表达式中(我仍然不完全理解,但是嘿,如果它有效)。新函数如下所示:


/*

function to display game sequence

length can be any integer greater than 1

speed is time between flashes in ms and can presently be set to 1000, 750, 500 and 250.

animation length for each speed is set by a corresponding speed class

in CSS main - .flashing1000 .flashing750 .flashing500 and .flashing250

*/

function displaySequence(length, speed) {

    var sequence = generateSequence(length);

    console.log(sequence);


    for (i = 0; i < sequence.length; i++) {

        console.log(sequence[i]);

        //       immediately invoked function expression

        (function(i) {

            setTimeout( function () {

                var sq = document.getElementById(sequence[i]);

                sq.classList.add('flashing' + speed.toString());

                sq.addEventListener('animationend', function() {

                    sq.classList.remove('flashing' + speed.toString());

                })

            }, (speed * i))

        })(i);

    }

}

每个类的 CSS:


@keyframes flash {

    0% {

        background: #333;

    }


    50% {

        background: orange

    }


    100% {

        background: #333;

    }

}


.flashing1000 {

    animation: flash 975ms;

}


.flashing750 {

    animation: flash 725ms;

}


.flashing500 {

    animation: flash 475ms;

}


.flashing250 {

    animation: flash 225ms;

}

我知道有一些懒惰的解决方法,但效果很好。


查看完整回答
反对 回复 2021-06-11
  • 2 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信