
Interactive Rating Component
Design comparison
Solution retrospective
What are you most proud of?
-
Successfully implemented an interactive rating component that dynamically updates the UI based on user input.
-
Improved code structure by organizing JavaScript event listeners efficiently.
What would you do differently next time?
-
Improve state management by using localStorage so that the rating persists even if the page refreshes.
-
Add a "rate again" button in the thank-you state so users can submit another rating without refreshing.
Challenge: Initially, clicking a rating button didn’t properly update the selected state, as multiple buttons could remain highlighted.
Solution: Used forEach to remove the active class from all buttons before adding it to the selected one:
ratingBtn.forEach((btn) => btn.classList.remove("active"));
button.classList.add("active");
This ensured only one rating could be selected at a time.
What specific areas of your project would you like help with?-
Are there any redundant lines of code in my JavaScript that could be optimized?
-
Does my CSS structure follow best practices? Could I improve it for better readability or maintainability?
-
Is there a better way to handle rating selection without using forEach to remove the active class from all buttons?
Community feedback
- P@huyphan2210Posted 14 days ago
Hi @rukhulkirom,
I've reviewed your solution, and I'd like to share some suggestions for improvement:
1️⃣ Use a CSS Naming Convention (e.g., BEM)
Using a convention like BEM can make your CSS more structured and easier to maintain. For example, instead of having
.card
and.thankyou-card
, you could use:.card { /* Base styling */ } .card--thank-you { /* Modifier for thank-you card */ }
This keeps your styles consistent and scalable.
2️⃣ Remove Unnecessary
id
AttributesYou assign
id
s to your cards but style them using classes instead. Since theid
s aren’t necessary, I recommend removing them to avoid redundancy.3️⃣ Use Semantic HTML for Better Accessibility
Instead of relying heavily on
<div>
, consider using semantic elements:- Use
<article>
instead of<div>
for your cards. - Wrap
<img>
elements inside<figure>
(or<picture>
for responsive images). - You’ve correctly used
<ul>
with<li>
for the.rating-btn
s—great! However, addtype="button"
to each.rating-btn
for better behavior.
4️⃣ Wrap Your Rating System Inside a
<form>
Instead of handling each button click separately, wrap your
<ul class="rating-buttons">
and.submit-btn
inside a<form>
, then:- Set
type="submit"
on.submit-btn
. - Handle the form’s submit event instead of attaching a click event to each rating button.
5️⃣ Optimize Your JavaScript with Event Delegation
If you're keeping the click event on each rating button instead of using a
<form>
, you can still make your JavaScript more efficient using Event Delegation:Before (Less Efficient)
ratingBtn.forEach((button) => { button.addEventListener("click", () => { ratingBtn.forEach((btn) => btn.classList.remove("active")); button.classList.add("active"); selectedRating = button.getAttribute("data-value"); }); });
After (More Efficient with Event Delegation)
document.querySelector(".rating-buttons").addEventListener("click", (event) => { const button = event.target.closest(".rating-btn"); if (!button) return; // Ignore clicks outside buttons document.querySelectorAll(".rating-btn").forEach((btn) => btn.classList.remove("active")); button.classList.add("active"); selectedRating = button.getAttribute("data-value"); });
✅ Why is this better?
- Only one event listener instead of one per button.
- Less memory usage and improved performance.
Hope this helps!
0 - Use
Please log in to post a comment
Log in with GitHubJoin our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord