Как сделать звездный рейтинг так, чтобы звезды можно было закрашивать при наведении и клике? Сейчас только через input работает.
<div class="rating rating_set">
<div class="rating__body">
<div class="rating__line"></div>
<div class="rating__activeline"></div>
<div class="rating__stars">
<input type="radio" class="rating__star" value="1" name="rating" />
<input type="radio" class="rating__star" value="2" name="rating" />
<input type="radio" class="rating__star" value="3" name="rating" />
<input type="radio" class="rating__star" value="4" name="rating" />
<input type="radio" class="rating__star" value="5" name="rating" />
</div>
<input value="5" type="text" name="rating" class="rating-input" />
</div>
</div>
.rating {
display: flex;
flex-wrap: wrap;
}
.rating__body {
display: inline-block;
position: relative;
width: 192px;
height: 32px;
}
.rating__body .rating-input {
display: none;
padding: 11px;
}
.rating__line {
position: absolute;
width: 192px;
height: 32px;
top: 0;
left: 0;
z-index: 1;
background: url("https://habrastorage.org/webt/8t/4a/k5/8t4ak5vv6tweelwxgccbyb0mpm0.png") 0 0 no-repeat;
background-size: 100% 100%;
}
.rating__activeline {
position: absolute;
height: 32px;
top: 0;
left: 0;
background: url("https://habrastorage.org/webt/yr/ct/s0/yrcts0ipk6fzpfnoe7_aobbkxmq.png") 0 0 no-repeat;
z-index: 2;
}
.rating__stars {
width: 100%;
display: flex;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.rating__star {
flex: 0 0 20%;
height: 100%;
opacity: 0;
}
const ratings = document.querySelectorAll(".rating")
if (ratings.length > 0) {
initRatings()
}
// Основная функция
function initRatings() {
let ratingActive, ratingValue
// "Бегаем" по всем рейтингам на странице
for (let index = 0; index < ratings.length; index++) {
const rating = ratings[index]
initRating(rating)
}
// Инициализируем конкретный рейтинг
function initRating(rating) {
initRatingVars(rating)
setRatingActiveWidth()
if (rating.classList.contains("rating_set")) {
setRating(rating)
}
}
// Инициализайция переменных
function initRatingVars(rating) {
ratingActive = rating.querySelector(".rating__activeline")
ratingValue = rating.querySelector(".rating-input")
}
// Изменяем ширину активных звезд
function setRatingActiveWidth() {
const ratingActiveWidth = ratingValue.value / 0.05
ratingActive.style.width = `${ratingActiveWidth}%`
}
ratingValue.addEventListener("change", function () {
setRatingActiveWidth()
})
// Возможность указать оценку
function setRating(rating) {
const ratingItems = rating.querySelectorAll(".rating__star")
for (let index = 0; index < ratingItems.length; index++) {
const ratingItem = ratingItems[index]
ratingItem.addEventListener("mouseenter", function (e) {
// Обновление переменных
initRatingVars(rating)
// Обновление активных звезд
setRatingActiveWidth(ratingItem.value)
})
ratingItem.addEventListener("mouseleave", function (e) {
// Обновление активных звезд
setRatingActiveWidth()
})
ratingItem.addEventListener("click", function (e) {
// Обновление переменных
initRatingVars(rating)
if (rating.dataset.ajax) {
// "Отправить" на сервер
setRatingValue(ratingItem.value, rating)
} else {
// Отобразить указанную оцнку
ratingValue.value = index + 1
setRatingActiveWidth()
}
})
}
}
}