Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.08.2019, 15:17
Новичок на форуме
Отправить личное сообщение для hostias Посмотреть профиль Найти все сообщения от hostias
 
Регистрация: 29.02.2016
Сообщений: 2

Рейтинг 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');
		}
	}
})();

Последний раз редактировалось hostias, 05.08.2019 в 18:11.
Ответить с цитированием
  #2 (permalink)  
Старый 05.08.2019, 15:35
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,121

Сообщение от hostias
сократить до 1 функции с перебором
Да хоть так...
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);
};
Ответить с цитированием
  #3 (permalink)  
Старый 05.08.2019, 16:12
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

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>
Ответить с цитированием
  #4 (permalink)  
Старый 05.08.2019, 18:23
Новичок на форуме
Отправить личное сообщение для hostias Посмотреть профиль Найти все сообщения от hostias
 
Регистрация: 29.02.2016
Сообщений: 2

Спасибо, поправил.
Если не затруднит еще просьба - так же и сократить беду с Хтмл чтоб на js он создавался реактивно без перезагрузки.
Вот эта беда с классом .rating и .rating-item. (чтоб уже комплект был полный)

Последний раз редактировалось hostias, 05.08.2019 в 18:39.
Ответить с цитированием
  #5 (permalink)  
Старый 05.08.2019, 19:41
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

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>

Последний раз редактировалось рони, 05.08.2019 в 23:45.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как с помощью jquery отсылать без перезагрузки... serhanters jQuery 11 22.07.2011 21:17
Конвертировать несколько строк jquery на mootools pro_xaoc jQuery 5 13.04.2011 20:19
как правильно прочесть xml без подключения jQuery BorodinKO Общие вопросы Javascript 1 03.04.2011 23:23
Несколько вопросов про jquery от новичка Delfi jQuery 3 24.11.2010 10:55
как сделать аналог jquery.load без jquery? vvsh AJAX и COMET 5 05.06.2009 22:40