Home > database >  Why I get undefined in last element
Why I get undefined in last element

Time:10-29

Why do I get undefined in the last element when I distribute the colors in elements?

  1. The work of code mixed colors in rows
  2. 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:

  1. Define a shuffle function
  2. Grab all the circle elements
  3. Set the background color for all circles, based on their data
  4. Shuffle the colors
  5. Grab a random color that is not the background, and remove it
  6. 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>

  • Related