I’m a beginner in JavaScript and I have a problem. I’m building a randomizing page, where I use 3 arrays and 3 buttons. I want it to expand with the answer (button 1 – array no1, button 2 – array no2, etc) when the button is clicked. But the problem is that I only get the answer to the querySelectorAll for the first button anyway and only it expands.
For now i using only one array, but i can’t figure out how to solve the problem of expanding buttons when they are clicked. How expand this button, which was clicked?
console.clear();
const color = ["red", "green", "blue", "aqua", "black", "purple", "yellow"];
const fruits = [{
type: "fruit",
name: "orange",
img: "https://t4.ftcdn.net/jpg/01/02/31/01/240_F_102310122_TyKkml1yRFle2IGtD2fAUrZLtixIGJqa.jpg"
},
{
type: "fruit",
name: "apple",
img: "https://t3.ftcdn.net/jpg/03/10/32/02/240_F_310320273_I9rR1l7918MJoZ0GRHGIBgZl9F9ShEXq.jpg"
},
{
type: "fruit",
name: "banana",
img: "https://t3.ftcdn.net/jpg/02/36/07/60/240_F_236076021_Lf2nHzSUcTxNGdG7hap6PjJNDwHT1VfC.jpg"
},
{
type: "fruit",
name: "mango",
img: "https://t4.ftcdn.net/jpg/00/52/87/43/240_F_52874381_Ucxx67h9KLuxSXiNGcsmHfSjAuqRXqDr.jpg"
},
{
type: "fruit",
name: "kiwi",
img: "https://t4.ftcdn.net/jpg/00/68/65/13/240_F_68651370_CVcQlAdJqvxtL8bIUm70UP1HwnFXOblQ.jpg"
},
{
type: "fruit",
name: "strawberries",
img: "https://t4.ftcdn.net/jpg/00/84/36/81/240_F_84368117_irN0O3akL7ALdMe17ZtxH6nya1cHiG5H.jpg"
},
{
type: "fruit",
name: "grape",
img: "https://t4.ftcdn.net/jpg/00/70/94/63/240_F_70946377_VJXdpJqld6XOsOTO6lt95ieZSxGO0faM.jpg"
},
{
type: "fruit",
name: "pear",
img: ""
}
];
let btns = document.querySelectorAll(".js-button");
let btn = document.querySelector(".js-button");
let isOpen = false;
let result = document.querySelector(".js-button-result");
let img = document.querySelector(".js-button-img");
let imgSrc = document.querySelector(".js-img");
btn.addEventListener("click", () => {
if (!isOpen) {
btn.classList.add("button--active");
img.classList.add("button-img--active");
result.classList.add("button-result--true");
//draw.classList.add("draw--open")
isOpen = true;
const rand = Math.floor(Math.random() * fruits.length);
result.innerHTML = fruits[rand].name;
imgSrc.src = fruits[rand].img;
} else {
btn.classList.remove("button--active");
img.classList.remove("button-img--active");
result.classList.remove("button-result--true");
//draw.classList.remove("draw--open")
isOpen = false;
}
});
window.addEventListener("click", (e) => {
if (e.target !== btn /*&& e.target !== draw*/ ) {
btn.classList.remove("button--active");
img.classList.remove("button-img--active");
result.classList.remove("button-result--true");
//draw.classList.remove("draw--open")
isOpen = false;
}
});
btns.forEach((i) => {
i.addEventListener("click", function() {
let dataValue = event.target.getAttribute("data-value");
/*if (!isOpen) {
btn.classList.add("button--active");
img.classList.add("button-img--active");
result.classList.add("button-result--true");
//draw.classList.add("draw--open")
isOpen = true;
const rand = Math.floor(Math.random() * fruits.length);
result.innerHTML = fruits[rand].name;
imgSrc.src = fruits[rand].img;
} else {
btn.classList.remove("button--active");
img.classList.remove("button-img--active");
result.classList.remove("button-result--true");
//draw.classList.remove("draw--open")
isOpen = false;
}
*/
});
});
* {
box-sizing: border-box;
font-size: 16px;
letter-spacing: 1px;
font-family: Montserrat, sans-serif;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: auto;
position: relative;
width: 30vw;
height: 30vh;
}
.button {
padding: 5% 0;
margin: 10px 0;
width: 100%;
height: auto;
text-align: center;
border-radius: 0 20px;
background-color: #dad7cd;
user-select: none;
transition: 100ms ease-in-out;
outline: 0;
}
.button--active {
position: absolute;
top: 0;
left: 0;
margin: 0;
height: 100%;
}
.button-result {
display: none;
}
.button-result--true {
display: block;
}
.button-img {
width: 150px;
height: 0;
margin: 0 auto;
display: flex;
justify-content: center;
border-radius: 20px;
overflow: hidden;
opacity: 0;
transition: all 0.6s ease-in-out;
}
.button-img--active {
height: 150px;
margin: 5% auto;
opacity: 1;
}
.button:hover {
outline: 2px solid #a3b18a;
background-color: #a3b18a;
outline-offset: 5px;
}
.button:active {
outline-offset: 8px;
}
<div class="wrapper">
<div class="js-button button button-1" data-value="1">
Click!
<div class="js-button-img button-img">
<img class="js-img" alt="No image!" />
</div>
<div class="js-button-result button-result">
Result
</div>
</div>
<div class="js-button button button-2" data-value="2">
Click!
<div class="js-button-img button-img">
<img class="js-img" alt="No image!" />
</div>
<div class="js-button-result button-result">
Result
</div>
</div>
<div class="js-button button button-3" data-value="3">
Click!
<div class="js-button-img button-img">
<img class="js-img" alt="No image!" />
</div>
<div class="js-button-result button-result">
Result
</div>
</div>
</div>
2
Answers
in your btns.forEach body, you use
btn.classList.add("button--active");
, the btn is not current element, it will not change with the iterator. you can usei
to replacebtn
I would suggest using a delegated event listener, bound to the parent DIV element (
.wrapper
) and inspect theevent.target
to determine if the event originated on the button. From that point the event handler will function for all buttons rather than a single button that might be identified usingquerySelector
You can simplify some of the above code by using the
toggle
method for the classList operations rather than theisOpen
logic block.The following does, I think, what you were trying to do(?) but uses a single listener. Perhaps it will help.