Как написать JS скрипт, присваивающий классы после нескольких кликов?
Есть html код, примерно такой:
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
Нужно сделать, что бы при клике по элементу box присваивался дополнительный класс opened, а по третьему клику присваивался класс bonus, и после этого скрипт заканчивал работу, после 3-го клика классы больше не присваиваются. Так же, элементу с классом opened не может быть присвоен класс bonus, т.е. классы присваиваются элементу только один раз. Помогите пожалуйста реализовать!
Ответы (4 шт):
Автор решения: highpassion
→ Ссылка
let items = document.querySelectorAll('.container .box'),
i = 0;
items.forEach((item) => {
item.addEventListener('click', (event) => {
i++;
if (i < 3) event.target.classList.add('opened');
else if (i == 3 && !(event.target.classList.contains('opened'))) {
event.target.classList.add('bonus');
}
});
});
.box {
background: red;
box-sizing: border-box;
padding: 42px;
width: 100px;
height: 100px;
text-align: center;
margin-bottom: 10px;
}
.opened {
background: green;
}
.bonus {
background: orange;
}
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
Автор решения: Dmitrii Sedov
→ Ссылка
ну, если я правильно всё понял. Надо что-то типо такого:
UPD дополнил ответ
const boxes = document.getElementsByClassName('box');
let countClick = 0;
[...boxes].map(box => {
box.addEventListener('click', function(e) {
if (countClick === 3 || this.classList.contains('opened')) return;
this.classList.add(countClick === 2 ? 'bonus' : 'opened');
countClick++;
});
})
.opened {
background: red;
}
.bonus {
background: blue;
}
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
Автор решения: UModeL
→ Ссылка
Как вариант, использовать делегирование, без лишних циклов:
document.querySelector('.container').addEventListener('click', function(ev) {
let classes = ev.target.classList;
if (this.querySelector('.bonus') || !classes.contains('box') || classes.contains('open')) return;
classes.add(((this.querySelectorAll('.open').length < 2) ? 'open' : 'bonus'));
});
.box { border: 1px dashed #080; }
.open { background-color: #fa0; }
.bonus { background-color: #f00;}
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
Автор решения: Pavel Nazarian
→ Ссылка
const bonus = function(e){
const t = e.target;
if (t.classList.contains('box')) {
if (this.querySelectorAll('.box.opened').length == 2){
t.className = 'box bonus';
this.removeEventListener('click',bonus);
} else t.className = 'box opened';
}
}
document.querySelector('.container').addEventListener('click',bonus)
.box {
border: 1px solid black;
margin: 10px;
height: 30px;
width: 30px;
}
.opened {
background: green;
pointer-events: none;
}
.bonus {
background: purple;
pointer-events: none;
}
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>