Star Review
by Paco86
HTML
<div id="root">
</div>
CSS
.star-review {
display: flex;
}
.star:before {
content: '★';
font-size: 1.5rem;
opacity: 0.1;
}
.star--active:before {
color: #3c74ff;
opacity: 1;
}
JavaScript
class StarReview {
constructor(root) {
this.root = root;
this.rating = 0;
this.stars = null;
this.onMouseOver = this.onMouseOver.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
this.onClick = this.onClick.bind(this);
}
init() {
this.generateStars();
this.stars = this.root.querySelectorAll('.star');
this.root.addEventListener('mouseover', this.onMouseOver);
this.root.addEventListener('mouseleave', this.onMouseLeave);
this.root.addEventListener('click', this.onClick);
}
generateStars() {
const stars = new Array(5).fill(null).map((_, index) => {
const activeClass = index + 1 <= this.rating ? 'star--active' : '';
return `
<div
class="star ${ activeClass }"
data-value="${ index + 1 }"
aria-label="Set star review to ${index + 1}"
aria-select="${ this.rating === index + 1 }">
</div>
`;
}).join('');
this.root.innerHTML = `
<div class="star-review">
${ stars }
</div>
`;
}
onMouseOver(event) {
this.rating = +event.target.dataset.value;
this.selectStar();
}
onMouseLeave() {
this.rating = 0;
this.selectStar();
}
onClick(event) {debugger
this.rating = +event.target.dataset.value;
this.root.removeEventListener('mouseover', this.onMouseOver);
this.root.removeEventListener('mouseleave', this.onMouseLeave);
this.root.removeEventListener('click', this.onClick);
}
selectStar() {
this.stars.forEach((starEl, index) => {
if (index < this.rating) {
starEl.classList.add('star--active');
} else {
starEl.classList.remove('star--active');
}
});
}
}
const starReview = new StarReview(document.querySelector('#root'));
starReview.init();