【问题标题】:Change colour on every iteration of forEach loop in javascript?在javascript中forEach循环的每次迭代中更改颜色?
【发布时间】:2021-03-28 10:01:48
【问题描述】:

我有一个函数可以短暂改变元素的颜色,然后将其改回原始颜色。根据您所处的级别(这是一个益智游戏),forEach 循环然后运行此函数一定次数(在更高级别更多)。目前,元素更改为的颜色是我手动输入到代码中的任何颜色。我正在尝试找到一种方法来在每次 forEach 运行该函数时更改该颜色。

例如,假设你在第一轮,forEach 运行了 3 次,元素会闪烁红白、红白、红白。我需要的是让它闪烁红白、蓝白、粉白。当颜色用完时,它还需要循环回到数组的开头。例如,在更高级别上,forEach 可能会运行 6 次,因此对颜色数组的迭代将不得不回到开始一次。代码如下:

function showCircle(item, j, x) {
  setTimeout(function () {
let x = 0;
let colors = ['blue','pink','green']
let color = colors[x];
    var num = initArray[j];
    var element = document.getElementById(num)
    element.classList.add(`cell-glow-${color}`)
    window.setTimeout(function () {
      element.classList.remove(`cell-glow-${color}`)
    }, 400);
    j++;
    x++
    console.log(color)
  }, speed() * j);
};

function showEachCircle(captureUserClicks) {
  initArray.forEach(showCircle);
  }

很明显,上面发生的事情是 showCircle 函数每次都将 x 归零,所以它在第一次迭代时卡住了。但我不确定我应该将这些变量放在哪里以使其正确迭代。另外,我什至还没有开始考虑强制数组回到开头。

有什么想法吗?谢谢!

【问题讨论】:

  • “红-白、蓝-白、粉-白”是指“蓝-白、粉-白、绿-白”吗?因为确实是代码中的颜色。
  • 什么是initarray?
  • 啊,所以我写的颜色完全是任意的。很抱歉造成混淆 - 我只是在演示功能,但实际值(颜色)可以是任何值。
  • InitArray 在函数外部定义,是函数运行的初始数组,用于指定应该更改哪些 DOM 元素。

标签: javascript arrays loops iteration


【解决方案1】:

我会这样做:

  • 为避免每次调用函数时都执行x=0,我们将把它放在它之外。

  • 为了遍历颜色数组,我们将利用模运算符:

     `x = (x+1)%3`
    

    这个,而不是x++ 将一遍又一遍地获得值0, 1, 2

  • array.forEach() 将多次调用该函数,而无需等待完整的闪光(从白色到红色再到白色)完成。我们将使用递归。完成一次完整的闪存后,如果需要,我们将再次调用该函数。

您可以在 sn-p 中看到一个工作示例:

const initArray = [1,1,1,1,1,1];
const colors = ['red', 'green', 'blue'];
let x = 0;
let numberOfFlashes = 0;
function showCircle() {
  setTimeout(()=> {
    color = colors[x];
    console.log(color);
    setTimeout(()=> {
      console.log('white');
      numberOfFlashes++;
      if(numberOfFlashes<initArray.length){
        showCircle();
      }
    }, 400);

    x = (x+1)%3;
  }, 400);
}

showCircle();

现在你可以只用你的代码代替我的控制台日志,你应该让它工作

【讨论】:

  • 非常感谢!在我接受之前,我将深入研究这两个答案——它们似乎都有很多非常有用的信息,但我是个菜鸟,所以在我弄清楚要使用哪个答案之前,我需要集中注意力!
【解决方案2】:

问题是您正在覆盖x,并且您正在尝试修改正在传入的数字j

首先,definition of forEach 有助于阅读。

具体来说,在你传入的函数中,showCircleitem是数组的当前项,j是循环的当前索引,x是原始数组,在在这种情况下,它将是initArray。然后,您将用let x = 0 覆盖x,并尝试增加j,这不会做任何事情,因为它在使用后会增加。

我认为您正在寻找类似这样的东西:

// Declare these outside the loop
var x = 0;
var colors = ['blue','pink','green'];

function showCircle(num, j) {
  // Save the current value so it isn't overwritten by the loop/setTimeout combination
  let y = x;
  // Increment x
  x++;
  setTimeout(function () {
    // Get the color, using the modulus operator (%) to start at the beginning again
    var color = colors[y % colors.length];
    // Get the element. num is the current item in the loop from initArray
    var element = document.getElementById(num);
    // Make it glow!
    element.classList.add(`cell-glow-${color}`)
    setTimeout(function () {
      // Make it not glow...
      element.classList.remove(`cell-glow-${color}`)
    }, 400);
    console.log(color);
    // j is the index of num in initArray
  }, speed() * j);
};

function showEachCircle(captureUserClicks) {
  initArray.forEach(showCircle);
}

如果你不熟悉modulus (or remainder) operator%,当你想要循环的东西有限时,循环非常有用,在这种情况下是colors。在这个例子中,有 3 种颜色:

0 % colors.length = 0
1 % colors.length = 1
2 % colors.length = 2
3 % colors.length = 0
4 % colors.length = 1
etc..

【讨论】:

  • 非常感谢!在我接受之前,我将深入研究这两个答案——它们似乎都有很多非常有用的信息,但我是个菜鸟,所以在我弄清楚要使用哪个答案之前,我需要集中注意力!
猜你喜欢
  • 2019-08-16
  • 2016-04-09
  • 2018-09-01
  • 2020-07-20
  • 1970-01-01
  • 2016-08-02
  • 2020-08-07
  • 2017-01-15
  • 2016-07-29
相关资源
最近更新 更多