Рейтинг 5 звезд несколько блоков без jQuery
Есть код, на рейтинг, все рабочее но нужен рефакторинг, - упростить и сократить js. Чтобы работали все блоки приходится писать 4 функции и менять только 1 переменную внутри них, кто может помочь оптимизоровать и сократить до 1 функции с перебором или любым другим методом?
Благодарю за любые комментарии)
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
.rating{
box-sizing: border-box;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
width: 166px;
margin: 37px 0 0 0;
position: relative;}
.rating-item {
transition: 0.3s linear;
width: 21px;
height: 20px;
background: black;
cursor: pointer;}
.rating-item.active, .rating-item.active ~ *, .rating-item:hover, .rating-item:hover ~ *
{background: #1c9fe7;}
</style>
<script>
document.addEventListener('click', ({target}) => {
if(target = target.closest('.rating-item')) {
const parent = target.parentNode,
activeElem = parent.querySelector('.active');
if(activeElem) activeElem.classList.remove('active');
target.classList.add('active');
}
})
</script>
</head>
<body>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
</body>
</html>
(function(){
var container = document.querySelector('.rating1');
var items = container.querySelectorAll('.rating-item')
container.onclick = function(e) {
if( ! e.target.classList.contains('active') ){
items.forEach(function(item){
item.classList.remove('active');
});
e.target.classList.add('active');
}
}
})();
(function(){
var container = document.querySelector('.rating2');
var items = container.querySelectorAll('.rating-item')
container.onclick = function(e) {
if( ! e.target.classList.contains('active') ){
items.forEach(function(item){
item.classList.remove('active');
});
e.target.classList.add('active');
}
}
})();
(function(){
var container = document.querySelector('.rating3');
var items = container.querySelectorAll('.rating-item')
container.onclick = function(e) {
if( ! e.target.classList.contains('active') ){
items.forEach(function(item){
item.classList.remove('active');
});
e.target.classList.add('active');
}
}
})();
(function(){
var container = document.querySelector('.rating4');
var items = container.querySelectorAll('.rating-item')
container.onclick = function(e) {
if( ! e.target.classList.contains('active') ){
items.forEach(function(item){
item.classList.remove('active');
});
e.target.classList.add('active');
}
}
})();
|
Цитата:
for (var i=1; i<5; i++) {
(function(N){
var container = document.querySelector('.rating'+N);
var items = container.querySelectorAll('.rating-item')
container.onclick = function(e) {
if( ! e.target.classList.contains('active') ){
items.forEach(function(item){
item.classList.remove('active');
});
e.target.classList.add('active');
}
}
})(i);
};
|
hostias,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
.rating{
box-sizing: border-box;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
width: 166px;
margin: 37px 0 0 0;
position: relative;}
.rating-item {
transition: 0.3s linear;
width: 21px;
height: 20px;
background: black;
cursor: pointer;}
.rating-item.active, .rating-item.active ~ *, .rating-item:hover, .rating-item:hover ~ *
{background: #1c9fe7;}
</style>
<script>
document.addEventListener('click', ({target}) => {
if(target = target.closest('.rating-item')) {
const parent = target.parentNode,
activeElem = parent.querySelector('.active');
if(activeElem) activeElem.classList.remove('active');
target.classList.add('active');
}
})
</script>
</head>
<body>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
<div class="rating">
<div class="rating-item" data-rate-ps="1"></div>
<div class="rating-item" data-rate-ps="2"></div>
<div class="rating-item" data-rate-ps="3"></div>
<div class="rating-item" data-rate-ps="4"></div>
<div class="rating-item" data-rate-ps="5"></div>
</div>
</body>
</html>
|
Спасибо, поправил.
Если не затруднит еще просьба - так же и сократить беду с Хтмл чтоб на js он создавался реактивно без перезагрузки. Вот эта беда с классом .rating и .rating-item. (чтоб уже комплект был полный) |
hostias,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
.rating{
box-sizing: border-box;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
width: 166px;
margin: 37px 0 0 0;
position: relative;}
.rating > div {
transition: 0.3s linear;
width: 21px;
height: 20px;
background: black;
cursor: pointer;}
.rating > div.active, .rating > div.active ~ *, .rating > div:hover, .rating > div:hover ~ *
{background: #1c9fe7;}
</style>
<script>
class Rating {
constructor(element, length = 5){
this.parent = element;
this.starLength = length;
this.stars = this.createElems(length);
this.parent.append(...this.stars);
this.parent.addEventListener("click", this.eventHandler.bind(this));
this.activeElem = this.stars[0];
}
createElems(length) {
let elems = Array.from({length}, () => document.createElement("div"));
return elems
}
eventHandler({target}){
if(this.stars.includes(target)){
this.activeElem.classList.remove("active");
this.activeElem = target;
this.activeElem.classList.add("active");
}
}
}
document.addEventListener("DOMContentLoaded", function() {
for (const element of document.querySelectorAll(".rating"))
new Rating(element, 5);
})
</script>
</head>
<body>
<div class="rating"></div>
<div class="rating"></div>
<div class="rating"></div>
<div class="rating"></div>
<div class="rating"></div>
</body>
</html>
|
| Часовой пояс GMT +3, время: 06:08. |