Рейтинг 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, время: 22:10. |