Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

290
Vistas
Sistema de calificación de estrellas personalizado de JavaScript

Quiero crear un sistema de clasificación por estrellas que tenga 5 estrellas. No puede seleccionar media estrella, solo una entera. Quiero lograr lo siguiente: si el usuario hace clic en la estrella, debe activarse la una y la otra anterior, y si el usuario hace clic en una estrella inferior, desactive todas las estrellas después de la seleccionada.

Esto es lo que obtuve hasta ahora: el usuario puede seleccionar 4 estrellas de cinco (en el quinto clic tengo un error que debe resolverse).

PD: Estoy trabajando con imágenes SVG, pero sería demasiado feo insertarlas, por lo que [ ] son las estrellas vacías (el valor predeterminado) y [X] son las estrellas seleccionadas (activas).

Aquí está mi código:

 for (let i = 1; i <= 5; i++) { document.getElementById("w__stars").innerHTML += `<span class="r__icon">[ ]</span>`; } var icon = document.getElementsByClassName("r__icon"); for (let i = 0; i < icon.length; i++) { icon[i].addEventListener("click", function (e) { console.log("--"); for (let j = 0; j < i+1; j++) { console.log("i: " +i); console.log("j: "+(j+1)); console.log("Rest: "+ (j+(5-(i+1)))); icon[j].innerHTML = `[X]`; icon[i+(5-(i+1))].innerHTML = `[ ]`; } }); }
 <div class="flex flex-row product-star-con" id="w__stars"></div>

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Su método solo necesita un enfoque diferente. Por ejemplo, ese bucle interno es innecesario si va a colocar esto allí icon[j].innerHTML = '[X]' .. que se puede colocar justo dentro del bucle externo.

Además, los cálculos innecesarios hacen que la tarea parezca más difícil de lo que realmente es. Y dado que se trata de un ciclo, la variable i siempre tendrá el valor más alto dentro del ciclo, ya que no hay una declaración de break allí.

El siguiente método apunta a los siguientes elementos y elementos anteriores en relación con el que se está haciendo clic en este momento y les aplica el ' innerHTML ' apropiado.

 // Function to get previous and next siblings of the target element function getSiblings(element, type){ var arraySib = []; if ( type == 'prev' ){ while ( element = element.previousSibling ){ arraySib.push(element); } } else if ( type == 'next' ) { while ( element = element.nextSibling ){ arraySib.push(element); } } return arraySib; } for (var i = 1; i <= 5; i++) { document.getElementById("w__stars").innerHTML += `<span class="r__icon">[ ]</span>`; } var icon = document.getElementsByClassName("r__icon"); for (var i = 0; i < icon.length; i++) { icon[i].addEventListener("click", function (e){ this.innerHTML = `[X]`; var prev = getSiblings(this, 'prev') var next = getSiblings(this, 'next') // populate previous siblings for(p = 0; p < prev.length; p++){ prev[p].innerHTML = `[X]` } // clear next siblings for(n = 0; n < next.length; n++){ next[n].innerHTML = `[]` } }); }
 <div class="flex flex-row product-star-con" id="w__stars"></div>

about 4 years ago · Juan Pablo Isaza Denunciar

0

Otro enfoque:

 // Setting stars const stars = []; for (let i = 0; i <= 4; i++) { stars.push({ active: false, index: i }); } const renderStars = (parentElement, stars, activeContent, notActiveContent) => { parentElement.innerHTML = ''; stars.forEach(({ active, index }) => { parentElement.innerHTML += ` <span class="r__icon">${active ? activeContent : notActiveContent}</span>`; }); Array.from(parentElement.querySelectorAll('.r__icon')).forEach((item, itemIndex) => { const star = stars.find(({ index }) => index === itemIndex); stars[star.index].element = item; item.addEventListener('click', (e) => { const itemElement = e.target; const starIndex = stars.findIndex(({ element }) => element === itemElement); if (starIndex === -1) { return; } const toActive = stars[starIndex].active !== true; stars = stars.map(star => { if (toActive) { // Set items before index to true, and after to false if (star.index <= starIndex) { return { ...star, active: true }; } return { ...star, active: false }; } else { // Set items after index to false, and before to true if (star.index >= starIndex) { return { ...star, active: false }; } return { ...star, active: true }; } }); renderStars(parentElement, stars, activeContent, notActiveContent); }); }); }; const setupStars = (stars, activeContent, notActiveContent) => { const parentElement = document.getElementById("w__stars"); if (!parentElement) { return; } renderStars(parentElement, stars, activeContent, notActiveContent); }; setupStars(stars, '[X]', '[ ]');
 <div class="flex flex-row product-star-con" id="w__stars"></div>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda