Estoy tratando de tener una función .forEach que haga que los divs se vuelvan rojos cuando mi mouse se desplace sobre ellos. Esto es lo que tengo hasta ahora:
canvas = document.getElementById('canvas'); boxes = document.querySelectorAll('div'); for (i=0; i<=2000; i++) { const box = document.createElement('div') box.classList.add('pixel') canvas.appendChild(box) } boxes.forEach((pixel) => { addEventListener('mouseover', function() { setTimeout(pixel.classList.add('red'), 5000); }) });en realidad no tienes que agregar otra lista de clases para tu div
solo puede usar CSS para hacer que el elemento se ponga rojo cada vez que lo desplace de esta manera
.pixel:hover { background-color : red, }y eso es
también, si desea hacer una animación y retrasar el div flotante, puede usar la propiedad de animación
pixel:hover { animation : color, animation-delay : 5s } @keyframes color { 0% { background-color : white } 100% { background-color : red } }eso es todo lo que necesitas con CSS, no necesitas JS
Hay algunos problemas con el código original que impiden que funcione como se esperaba:
boxes está vacío porque en el momento de ejecutar querySelectorAll('div') , no existen divs. A menos que su canvas también sea un div, en cuyo caso solo encontrará el elemento canvas div. De lo contrario, vacío.
Al usar addEventListener , está invocando window.addEventListener (es decir, el addEventListener de nivel superior), que actúa en la ventana misma. Desea apuntar a cada elemento, por lo que debe usar pixel.addEventListener (pero más sobre esto en un momento).
Entonces, modificando ligeramente su solución actual moviendo la búsqueda de elementos de clase de pixel DESPUÉS del ciclo de creación + haciendo pixel.addEventListener , que adjunta el detector de eventos a cada div de píxeles, el siguiente fragmento funciona. (Pero sigue leyendo después del fragmento).
canvas = document.getElementById('canvas'); const DELAY = 0; for (i = 0; i <= 20; i++) { const box = document.createElement('div') box.classList.add('pixel') canvas.appendChild(box) } boxes = Array.from(document.getElementsByClassName('pixel')); boxes.forEach((pixel) => { pixel.addEventListener('mouseover', function() { setTimeout(() => pixel.classList.add('red'), DELAY); }) pixel.addEventListener('mouseout', function() { setTimeout(() => pixel.classList.remove('red'), DELAY); }) }); .pixel { width: 32px; height: 32px; background-color: black; margin: 4px; } .red { background-color: red; } <section id="canvas"> </section>Sin embargo, en el ejemplo anterior, son solo 20 detectores de eventos. Tampoco funciona si agrega dinámicamente más elementos de píxeles; no tendrán los detectores de eventos asociados. En su código original, quiere 2000 elementos. Son 2000 oyentes de eventos en la página (4000 si hizo mi ejemplo agregando un evento mouseout también para eliminar la clase agregada).
Una mejor manera de escalar esto para una gran cantidad de elementos dinámicos es simplemente tener 1 detector de eventos en la página y verificar a qué elemento se dirige:
document.addEventListener('click',function(e){ if(e.target && e.target.classes.includes('pixel')){ e.target.classList.add('red'); } });Esto crea un detector de eventos único y dinámico en todo el documento que verifica el objetivo sobre el que se encuentra. De esta manera, ya sea que tenga 2000 o 2 millones de elementos, solo tiene 1 detector de eventos que verifica efectivamente su estado de desplazamiento.
Nota: si todo lo que quiere hacer es cambiar el color, puede usar la otra respuesta y hacerlo a través de CSS sin ningún tipo de manejo de eventos. Pero si tiene una razón para hacer esto dentro de javascript (es decir, color dinámico, tal vez quiera que se ejecute algún otro código de javascript cuando se pasa el cursor sobre algo), el enfoque anterior es ideal.