Как рандомно менять цвет у блока

Есть например несколько блоков. Как можно скриптом указать 4 цвета, по умолчанию, которые будут менять фон program рандомно при заходе на страницу. Но чтобы при этом не повторялись. А если блоков больше 4, то выводить цвет из заданных заново.

<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>


Ответы (3 шт):

Автор решения: Алексей Шиманский

Чтобы присвоить всем блокам цвет без повторений надо:

  1. Объявить массив с цветами.
  2. Перемешать массив любым алгоритмом (их минимум десяток)
  3. Далее уже в из перемешанного массива по порядку в цикле брать цвета и так же по порядку присваивать их блокам.
  4. PROFIT
→ Ссылка
Автор решения: Проста Miha

Вот метод с использованием Array.splice()

const programBLocks = document.querySelectorAll('.program');
const colors = ['red', 'blue', 'yellow', 'green'];

function randomGenerateColor() {
  let tempColors = [...colors];
  programBLocks.forEach(element => {
    let countColors = tempColors.length;

    if (countColors === 0) {
      tempColors = [...colors];
    }

    let colorIndex = generateRandomNumber(0, tempColors.length);
    let color = tempColors[colorIndex];
    element.style.backgroundColor = color;
    tempColors.splice(colorIndex, 1);
  })
}

function generateRandomNumber(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}

randomGenerateColor();
body {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.program {
  width: 120px;
  height: 120px;
}
<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>

<div class="item">
  <div class="program"></div>
</div>

→ Ссылка
Автор решения: IvaMuxa

Генерируем произвольную последовательность из чисел от нуля до количества цветов и перебираем её по кругу в качестве индексов для массива с цветами.

const colors = ['red', 'blue', 'yellow', 'green'];

function generateRandomSequence(max) {
  let sequence = [0];
  for (let i = 1; i < max; i++) {
    sequence.splice(Math.floor(Math.random() * sequence.length), 0, i)
  }
  return sequence;
}

let s = generateRandomSequence(colors.length);
let i = 0;
document.querySelectorAll('.program').forEach(element => {
  element.style.backgroundColor = colors[s[(i++) % colors.length]];
})
body {
  display: flex;
  flex-wrap: wrap;
}

.program {
  width: 50px;
  height: 50px;
}
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>
<div class="item">
  <div class="program"></div>
</div>

→ Ссылка