Introduzione al sistema di rating
I sistemi di rating sono ormai onnipresenti in applicazioni web e piattaforme di ogni tipo: e-commerce, siti di recensioni, app di delivery e persino portali aziendali interni. Il rating permette agli utenti di esprimere in modo immediato e intuitivo il proprio feedback. Da un punto di vista frontend, implementare un sistema di questo tipo offre l’occasione di rafforzare le competenze su gestione eventi, manipolazione del DOM e CSS interattivo.
In questo articolo vedremo come costruire un sistema di valutazione (rating system) usando HTML, CSS e JavaScript puro, partendo dalla struttura, passando per il design e arrivando alla logica di interazione e salvataggio.
Struttura HTML di base
Partiamo da un markup essenziale. L’obiettivo è avere un contenitore con 5 stelle, pronte a ricevere l’interazione dell’utente.
<div class="rating">
<span data-value="5">★</span>
<span data-value="4">★</span>
<span data-value="3">★</span>
<span data-value="2">★</span>
<span data-value="1">★</span>
</div>
Ogni <span>
rappresenta una stella, con un data-value
che indica il valore associato. Questa struttura semantica è semplice, ma efficace: ci garantisce di poter rilevare facilmente quale stella è stata cliccata.
Implementazione della logica con JavaScript
Ora aggiungiamo lo script JavaScript che intercetta il clic e aggiorna lo stato del rating.
const stars = document.querySelectorAll('.rating span');
const ratingOutput = document.getElementById('rating-value');
stars.forEach(star => {
star.addEventListener('click', () => {
const value = star.getAttribute('data-value');
updateRating(value);
});
});
function updateRating(value) {
// Resetta tutte le stelle
stars.forEach(star => {
star.classList.remove('active');
});
// Attiva le stelle fino a quella selezionata
stars.forEach(star => {
if (star.getAttribute('data-value') <= value) {
star.classList.add('active');
}
});
ratingOutput.textContent = `Valutazione: ${value}/5`;
}
Il cuore della logica è la funzione updateRating
, che aggiorna lo stato visivo e il testo mostrato all’utente. Concetti simili tornano utili quando si approfondisce la manipolazione del DOM e il ciclo della sua vita.
Aggiunta di stili CSS per il design
L’aspetto delle stelle è fondamentale per un corretto coinvolgimento dell’utente. Possiamo sfruttare pseudo-classi e hover per rendere l’esperienza più ricca.
.rating {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
cursor: pointer;
font-size: 2rem;
}
.rating span {
color: #ccc;
transition: color 0.3s;
}
.rating span:hover,
.rating span:hover ~ span {
color: #f5b301;
}
.rating span.active {
color: #f5b301;
}
La scelta di usare flex-direction: row-reverse
semplifica la gestione dell’ordine visivo tipico delle stelle. Inoltre, la regola span:hover ~ span
consente di evidenziare più stelle al passaggio del mouse. Stiamo sfruttando meccaniche CSS simili a quelle viste quando si lavora su stili isolati e gestione della cascata.
Gestione degli eventi di clic
Abbiamo aggiunto un EventListener
su ciascuna stella che richiama updateRating
. Questo approccio è molto intuitivo, ma può diventare meno efficiente in presenza di molteplici widget. Una variante è quella di applicare il listener al contenitore e usare event delegation.
document.querySelector('.rating').addEventListener('click', (e) => {
if (e.target.tagName === 'SPAN') {
const value = e.target.getAttribute('data-value');
updateRating(value);
}
});
Il vantaggio è che utilizziamo un unico listener, migliorando le performance e la manutenibilità del codice: concetti che tornano spesso esplorando come gestire eventi con addEventListener o ottimizzare la manipolazione reattiva del DOM in framework complessi come React (tecniche di ottimizzazione del DOM).
Salvataggio dei dati di rating
Spesso non basta aggiornare il DOM locale: bisogna inviare la valutazione al server. Questo comporta una chiamata fetch a un endpoint, con adeguata gestione errori.
function sendRating(value) {
fetch('/api/rating', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ rating: value })
})
.then(res => {
if (!res.ok) throw new Error('Errore di rete');
return res.json();
})
.then(data => {
console.log('Rating salvato', data);
})
.catch(err => {
console.error('Errore durante il salvataggio', err);
});
}
In scenari reali sarà utile una robusta gestione degli errori fetch con retry. Ricorda che il salvataggio è fondamentale per rendere persistente il feedback e utilizzabile dai sistemi di analisi.
Test e debug del sistema
Come ogni componente, anche un sistema di rating va testato: occorre verificare comportamento all’hover, corretta attribuzione delle classi active
, stabilità delle chiamate fetch, UI responsive. Spesso conviene costruire widget riutilizzabili e compatibili con altre parti della UI. Qui si collegano concetti trattati nello sviluppo di widget interattivi con Web Components, o anche nel design di componenti fluidi con ResizeObserver per ridimensionamenti dinamici.
In fase di debug è utile loggare eventi e valori selezionati. Testare su diversi browser e device assicura consistenza di esperienza. Inoltre, favorire approcci modulari consente in futuro di migrarlo verso framework emergenti come quelli descritti in framework JS emergenti.
Conclusione
Abbiamo visto come creare un sistema di rating con HTML, CSS e JavaScript, partendo dal markup semplice fino alla gestione eventi, logica di selezione e salvataggio dati. Una volta padroneggiATI questi concetti, puoi estendere facilmente il widget con animazioni più complesse, local storage, oppure integrazione con API pubbliche. Non solo un esercizio didattico, ma una base solida per rendere i progetti frontend più interattivi e orientati al coinvolgimento dell’utente.