Why do I get undefined
in the last element when I distribute the colors in elements?
- The work of code mixed colors in rows
- I try to set named colors in the circle without repeating the same color and without being same color of circle
Problem: I get undefined
instead of getting the desired color
let ar = document.getElementsByClassName('row');
let classNameArray = [];
let withoutItem = [],
arrayWithoutCurrentColor,
currentColor;
let shuffle = array => {
let arr = [];
for (let ii = 0; ii < array.length; ii ) {
arr.push(array[ii])
}
let len = arr.length,
random, temp;
while (len > 0) {
random = Math.floor(Math.random() * len);
len--;
temp = arr[len]; // save temp value to don't take new value bcz we change it to random index
arr[len] = arr[random];
arr[random] = temp;
}
return arr;
}
let search_by_name = (name, array) => {
let numx;
array.forEach((el, key) => el == name ? numx = key : '')
return numx;
};
let remove_item = (name, array) => {
let array1 = [];
for (let ii = 0; ii < array.length; ii ) {
array1.push(array[ii])
}
withoutItem = array1;
withoutItem.splice(search_by_name(name, array1), 1); // remove first element
console.log("i remove " name);
return array1;
}
for (let i = 0; i < ar.length; i ) {
// [1] select bg color
const element = document.getElementsByClassName('row')[i];
let elelmentClassName = document.getElementsByClassName('row')[i].className;
let firstClassName = elelmentClassName.split(' ')[1];
element.style.backgroundColor = firstClassName;
// [2] add color from class element to array
classNameArray.push(elelmentClassName.split(' ')[1]); // array with colors
}
// [3] shuffle color arrary
let shuffledArray = shuffle(classNameArray)
for (let indexColor = 0; indexColor < classNameArray.length; indexColor ) { // turn 9
const element = document.getElementsByClassName('row')[indexColor];
const color = classNameArray[indexColor];
// [4] remove same bgcolor
arrayWithoutCurrentColor = remove_item(color, shuffledArray);
currentColor = arrayWithoutCurrentColor[(8 - 1) - indexColor]; // lentgh - 1 for index & (-1) removed element
// [5] append name color in element
element.innerHTML = `<span style="color : ${currentColor}"> ${currentColor} </span>`;
// [6] remove thee added color to don't repeat same color
shuffledArray.splice(search_by_name(currentColor, shuffledArray), 1);
}
body {
background-color: #eeeeee;
display: flex;
justify-content: center;
flex-direction: column;
}
.con {
display: flex;
justify-content: space-between;
width: 100%;
}
.row {
margin: 20px;
width: 150px;
height: 150px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.row span {
font-size: 23px;
}
<div >
<div ></div>
<div ></div>
<div ></div>
</div>
<div >
<div ></div>
<div ></div>
<div ></div>
</div>
<div >
<div ></div>
<div ></div>
<div ></div>
</div>
CodePudding user response:
You can simplify your code to the following:
- Define a shuffle function
- Grab all the circle elements
- Set the background color for all circles, based on their data
- Shuffle the colors
- Grab a random color that is not the background, and remove it
- Apply the color text
Note: Do not abuse class names, put the data into a data attribute.
const shuffle = (arr) => arr.sort(() => Math.random() - 0.5);
const remove = (arr, e, amt = 1) => arr.splice(arr.findIndex((x) => x !== e), amt);
const getColor = (el) => el.getAttribute('data-color');
const circles = document.querySelectorAll('.row');
// Set colors
circles.forEach((el) => el.style.backgroundColor = getColor(el));
// Random color
let randColors = shuffle([...circles].map((el) => getColor(el)));
// Apply random color text to circles
circles.forEach((circle) => {
const [color] = remove(randColors, circle);
circle.innerHTML = `<span style="color:${color}">${color}</span>`;
});
body {
background-color: #eeeeee;
display: flex;
justify-content: center;
flex-direction: column;
}
.con {
display: flex;
justify-content: space-between;
width: 100%;
}
.row {
margin: 20px;
width: 150px;
height: 150px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.row span {
font-size: 23px;
}
<div >
<div data-color="yellow"></div>
<div data-color="red"></div>
<div data-color="black"></div>
</div>
<div >
<div data-color="white"></div>
<div data-color="green"></div>
<div data-color="brown"></div>
</div>
<div >
<div data-color="lightpink"></div>
<div data-color="orange"></div>
<div data-color="orchid"></div>
</div>