我是 JavaScript 的初学者,我有一个问题。我正在构建一个随机化页面,我在其中使用 3 个数组和 3 个按钮。我希望它在单击按钮时用答案(按钮 1 - array no1,button 2 - array no2 等)展开。但问题是,无论如何我只能得到第一个按钮的 querySelectorAll 的答案,而且只会展开。
目前我只使用一个数组,但我无法弄清楚如何解决单击时展开按钮的问题。怎么展开这个被点击的按钮?
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>
我建议使用委托事件侦听器,绑定到父 DIV 元素 (
.wrapper
) 并检查 event.target
以确定事件是否起源于按钮。从那时起,事件处理程序将对所有按钮起作用,而不是可能使用 querySelector
识别的单个按钮
您可以通过对 classList 操作使用
toggle
方法而不是 isOpen
逻辑块来简化上面的一些代码。
我认为,以下内容确实是您想要做的(?),但使用了一个侦听器。也许会有帮助。
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"
}
];
const d = document;
// class names used
const css = {
'bttn': 'js-button',
'active': 'button--active',
'bttnresult': 'js-button-result',
'bttnrestrue': 'button-result--true',
'img': 'button-img--active'
};
// parent node to bind delegated listener to
const wrapper = d.querySelector('div.wrapper');
// create a pseudo random number between low & high bounds
const mt_rand = (a, b) => Math.floor(Math.random() * (b - a + 1) + a);
// use the random number to return a random item from an input array
const getarray = (src) => src[mt_rand(0, src.length - 1)];
let is_open = false; // global boolean to indicate panel open status
let img_src; // store reference to selected fruit image for use when closing panel
wrapper.addEventListener('click', e => {
if (e.target instanceof HTMLDivElement && e.target.classList.contains(css.bttn) && e.target.parentNode == wrapper) {
// find the dataset attribute(s)
let value = Number( e.target.dataset.value );
// find the IMG element
let img = e.target.querySelector('img');
// find the div that will display the fruit name
let result = e.target.querySelector(`.${css.bttnresult}`);
// select a random fruit ( or other type of "thing" )
let fruit = getarray(fruits);
// toggle the class for current button/panel and associated child elements
e.target.classList.toggle(css.active);
result.classList.toggle(css.bttnrestrue);
result.textContent = !is_open ? fruit.name : '';
img.parentNode.classList.toggle(css.img);
img.src = !is_open ? fruit.img : img_src;
img.alt = !is_open ? fruit.name : 'No image!';
console.info('Panel:%d is open:%s', value, !is_open)
// toggle the global boolean variable to indicate open status
is_open = !is_open;
img_src = fruit.img;
}
});
* {
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;
cursor: pointer;
}
.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;
z-index: 100;
}
.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"></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"></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"></div>
</div>
</div>
btns.forEach((i) => {
i.addEventListener("click", function() {
let dataValue = event.target.getAttribute("data-value");
/*if (!isOpen) {
//btn.classList.add("button--active");
i.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");
i.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 主体中,你使用
btn.classList.add("button--active");
,btn 不是当前元素,它不会随着迭代器而改变。你可以用i
代替btn