У меня есть функция, которая ненадолго меняет цвет элемента, а затем возвращает его к исходному цвету. В зависимости от уровня, на котором вы находитесь (это игра-головоломка), цикл forEach запускает эту функцию определенное количество раз (больше на более высоких уровнях). В настоящее время цвет, на который изменяется элемент, — это то, что я вручную ввел в код. Я пытаюсь найти способ изменить этот цвет каждый раз, когда forEach запускает функцию.
Например, скажем, вы находитесь в первом раунде, и forEach выполняется три раза, элемент будет мигать красно-белым, красно-белым, красно-белым. Мне нужно, чтобы он мигал красно-белым, сине-белым, розово-белым. Он также должен вернуться к началу массива, когда у него закончатся цвета. Например, на более высоком уровне 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.info(color)
}, speed() * j);
};
function showEachCircle(captureUserClicks) {
initArray.forEach(showCircle);
}
Ясно, что выше происходит то, что функция showCircle каждый раз обнуляет x, поэтому она застревает на первой итерации. Но я не уверен, куда мне следует поместить эти переменные, чтобы они правильно повторялись. Кроме того, я даже не начал думать о том, чтобы заставить массив вернуться к началу.
Есть идеи? Спасибо!
что такое инитаррей?
Итак, цвета, которые я написал, совершенно произвольны. Извиняюсь за путаницу - я просто демонстрировал функциональность, но фактические значения (цвета) могут быть любыми.
InitArray определен вне функции и представляет собой начальный массив, через который проходит функция, чтобы указать, какие элементы DOM следует изменить.
Проблема в том, что вы перезаписываете x
и пытаетесь изменить число j
, которое передается.
Во-первых, полезно прочитать определение forEach.
В частности, в функции, которую вы передаете, showCircle
, item
— текущий элемент массива, j
— текущий индекс цикла, а x
— исходный массив, в данном случае это будет initArray
. Затем вы перезаписываете x
на let x = 0
и пытаетесь увеличить 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.info(color);
// j is the index of num in initArray
}, speed() * j);
};
function showEachCircle(captureUserClicks) {
initArray.forEach(showCircle);
}
Если вы не знакомы с оператором модуля (или остатка)%
, он очень полезен для циклов, когда у вас есть ограниченный набор вещей, которые вы хотите перебрать, в данном случае colors
. В этом примере с 3 цветами:
0 % colors.length = 0
1 % colors.length = 1
2 % colors.length = 2
3 % colors.length = 0
4 % colors.length = 1
etc..
большое спасибо! Я собираюсь подробно изучить оба этих ответа, прежде чем принять их - они оба, кажется, содержат много действительно полезной информации, но я новичок, поэтому мне потребуется некоторая концентрация, прежде чем я выясню, какой из них использовать!
Вот как бы я это сделал:
Чтобы избежать выполнения x=0
каждый раз, когда вы вызываете функцию, мы поместим его за ее пределы.
Чтобы перебрать массив цветов, мы воспользуемся оператором по модулю:
`x = (x+1)%3`
Это вместо x++
будет получать значения 0, 1, 2
снова и снова.
array.forEach()
будет вызывать функцию несколько раз, не дожидаясь завершения полной вспышки (от белого к красному и обратно к белому). Вместо этого мы будем использовать рекурсию. Как только полная прошивка будет завершена, мы снова вызовем функцию, если это необходимо.
Вы можете увидеть рабочий пример во фрагменте:
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.info(color);
setTimeout(()=> {
console.info('white');
numberOfFlashes++;
if (numberOfFlashes<initArray.length){
showCircle();
}
}, 400);
x = (x+1)%3;
}, 400);
}
showCircle();
Теперь вы можете просто поместить свой код вместо моих журналов консоли, и вы должны заставить его работать.
большое спасибо! Я собираюсь подробно изучить оба этих ответа, прежде чем принять их - они оба, кажется, содержат много действительно полезной информации, но я новичок, поэтому мне потребуется некоторая концентрация, прежде чем я выясню, какой из них использовать!
Под "красно-белым, сине-белым, розово-белым" вы имеете в виду "сине-белый, розово-белый, зелено-белый"? Потому что это цвета в вашем коде.