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

我有一个由 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;

}


料青山看我应如是
浏览 166回答 2
2回答

沧海一幻觉

试试这个:function flash(index, delay){&nbsp; &nbsp; setTimeout( function() {&nbsp; &nbsp; &nbsp; &nbsp; flashingSquare = document.getElementById(index);&nbsp; &nbsp; &nbsp; &nbsp; flashingSquare.classList.add('flashing');&nbsp; &nbsp; &nbsp; &nbsp; flashingSquare.addEventListener('animationend', function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; flashingSquare.classList.remove('flashing');&nbsp; &nbsp; &nbsp; &nbsp; }, delay);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; });}不要删除动画,删除 class。动画完成后直接删除类。所以浏览器有时间处理所有事情。当您在需要动画之前直接添加类时,浏览器可以触发所有需要的步骤来执行此操作。您删除和添加课程的尝试很好,但速度很快。我认为浏览器和 DOM 优化了你的步骤并且什么都不做。

温温酱

经过一番研究,我想出了一个解决方法。我重写了函数,以便 setTimeout 嵌套在 for 循环中,setTimeout 嵌套在立即调用的函数表达式中(我仍然不完全理解,但是嘿,如果它有效)。新函数如下所示:/*function to display game sequencelength can be any integer greater than 1speed 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 classin CSS main - .flashing1000 .flashing750 .flashing500 and .flashing250*/function displaySequence(length, speed) {&nbsp; &nbsp; var sequence = generateSequence(length);&nbsp; &nbsp; console.log(sequence);&nbsp; &nbsp; for (i = 0; i < sequence.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; console.log(sequence[i]);&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; &nbsp;immediately invoked function expression&nbsp; &nbsp; &nbsp; &nbsp; (function(i) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout( function () {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var sq = document.getElementById(sequence[i]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sq.classList.add('flashing' + speed.toString());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sq.addEventListener('animationend', function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sq.classList.remove('flashing' + speed.toString());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, (speed * i))&nbsp; &nbsp; &nbsp; &nbsp; })(i);&nbsp; &nbsp; }}每个类的 CSS:@keyframes flash {&nbsp; &nbsp; 0% {&nbsp; &nbsp; &nbsp; &nbsp; background: #333;&nbsp; &nbsp; }&nbsp; &nbsp; 50% {&nbsp; &nbsp; &nbsp; &nbsp; background: orange&nbsp; &nbsp; }&nbsp; &nbsp; 100% {&nbsp; &nbsp; &nbsp; &nbsp; background: #333;&nbsp; &nbsp; }}.flashing1000 {&nbsp; &nbsp; animation: flash 975ms;}.flashing750 {&nbsp; &nbsp; animation: flash 725ms;}.flashing500 {&nbsp; &nbsp; animation: flash 475ms;}.flashing250 {&nbsp; &nbsp; animation: flash 225ms;}我知道有一些懒惰的解决方法,但效果很好。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript