Reputation: 287
I'm a JS learner. I'm trying to build a flip-card game. It's just the beginning stage. I came across a tutorial how to make a single flip-card. But I want to have several flip-cards. I figured out myself how to add event listeners to each card. Yet, I wonder if it is possible to refactor this JS code if I want to add more cards. I would have to copy the same lines of code. Can you help me in some easy vanilla way :)? Or maybe it's the only way?
<!-- ####### CARD 1 ######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Dark Knight</h3>
<p>Attack 12</p>
</div>
</div>
</div>
</div>
</div>
<!-- ####### CARD 2######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Unicorn</h3>
<p>Attack 6</p>
</div>
</div>
</div>
</div>
</div>
<!-- ####### CARD 3 ######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Squirrel</h3>
<p>Attack 1</p>
</div>
</div>
</div>
</div>
</div>
const card = document.querySelectorAll(".card");
const cardInner = document.querySelectorAll(".card__inner");
card[0].addEventListener("click", function () {
cardInner[0].classList.toggle("is-flipped");
});
card[1].addEventListener("click", function () {
cardInner[1].classList.toggle("is-flipped");
});
card[2].addEventListener("click", function () {
cardInner[2].classList.toggle("is-flipped");
});
Upvotes: 0
Views: 166
Reputation: 122906
You may want to consider using event delegation. For example:
document.addEventListener(`click`, handle);
function handle(evt) {
if (evt.target.closest(`.card`)) {
return evt.target
.closest(`.card`)
.querySelector(`.card__inner`)
.classList.toggle(`is-flipped`);
}
}
.card {
cursor: pointer;
}
.is-flipped {
color: green;
font-weight: bold;
}
<!-- ####### CARD 1 ######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Dark Knight</h3>
<p>Attack 12</p>
</div>
</div>
</div>
</div>
</div>
<!-- ####### CARD 2######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Unicorn</h3>
<p>Attack 6</p>
</div>
</div>
</div>
</div>
</div>
<!-- ####### CARD 3 ######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Squirrel</h3>
<p>Attack 1</p>
</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 45943
You could use forEach()
function, like so :
const cards = document.querySelectorAll(".card");
const cardInners = document.querySelectorAll(".card__inner");
cards.forEach((c,index)=>c.addEventListener("click", function () {
cardInners[index].classList.toggle("is-flipped");
}))
<!-- ####### CARD 1 ######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Dark Knight</h3>
<p>Attack 12</p>
</div>
</div>
</div>
</div>
</div>
<!-- ####### CARD 2######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Unicorn</h3>
<p>Attack 6</p>
</div>
</div>
</div>
</div>
</div>
<!-- ####### CARD 3 ######### -->
<div class="card">
<div class="card__inner">
<div class="card__face card__face--front">
<h2>GAME</h2>
</div>
<div class="card__face card__face--back">
<div class="card__content">
<div class="card__header">
<img src="" alt="" />
</div>
<div class="card__body">
<h3>Squirrel</h3>
<p>Attack 1</p>
</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 312
Using foreach
const card = document.querySelectorAll(".card");
const cardInner = document.querySelectorAll(".card__inner");
for(let i=0; i < card.length; i++){
card.item(i).addEventListener("click", function () {
cardInner.item(i).classList.toggle("is-flipped");
});
}
Upvotes: 1
Reputation: 603
How I would do this is with the .forEach function of JavaScript. Here an example of how I would use this:
const cards = document.querySelectorAll('.card')
const onCardClick = async (e) => {
// prevent default if you want
e.preventDefault()
// your function
}
if (typeof cards !== 'undefined' && cards != null) {
cards.forEach(function(card) {
card.addEventListener('click', onCardClick)
})
}
Upvotes: 0