为什么事件处理程序只在第一个项目元素处切换 class 名称而不是其余的?
Why does the event handler toggle the class name just at the first item element but not for the rest?
我看到 class 被主动添加到第一个元素的控制台中,但仅限于第一个元素。事件侦听器绑定到 svg 按钮。 Class 'open' 把 'hidden-block' display 变成 display: block;在项目容器中
const faqDropDown = document.querySelector(".accordion-icon");
const faqContainer = document.querySelector(".item");
faqDropDown.addEventListener("click", function() {
faqContainer.classList.toggle("open");
});
.item { margin-bottom: 10px; }
p { margin: 0; }
svg { width 1em; height: 1em; margin: 10px; }
<div class="item">
<p class="number">01</p>
<p class="text">lorem ipsum ist?</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
Et, tempore repudiandae. Minima, cupiditate totam nihil
laborum rem sit, est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
<div class="item">
<p class="number">02</p>
<p class="text">lorem ipsum ist?</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
Et, tempore repudiandae. Minima, cupiditate totam nihil
laborum rem sit, est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
你的问题是你正在使用 querySelector
它将 return 它遇到的第一个对象,这意味着它将 return 只有第一个项目 .item
.
为了对带有 class 的多个项目应用一些更改(我想你有多个 class="item"
),你需要使用 querySelectorAll
,这将 return具有 class item
.
的节点数组
下面我给你留下了一个例子,说明如何使用 querySelectorAll
然后遍历每个节点,然后应用你想要的更改。
注意:如果您查看代码,html 是我制作的,只是为了证明它有效(它将所有项目更改为红色)。 javascript 部分是更改为对所有项目进行正确更改的部分。只需将其复制粘贴到您的代码中即可。
const faqDropDown = document.querySelector(".accordion-icon");
const faqContainers = document.querySelectorAll(".item");
faqDropDown.addEventListener("click", function() {
faqContainers.forEach(faqContainer => {
faqContainer.classList.toggle("open");
})
});
.open {
color: red;
}
<button class="accordion-icon">
toggle open
</button>
<div class="item">
item1
</div>
<div class="item">
item2
</div>
<div class="item">
item3
</div>
<div class="item">
item4
</div>
OP 需要处理手风琴所有项目的状态。因此,对于提供的示例,必须为每个项目的 svg 图标注册一个事件处理程序。
处理程序不仅需要处理项目的切换状态,还需要检测和处理关闭所有其他项目的情况...
function handleAccordionItemStates({ currentTarget }) {
const currentItem = currentTarget.closest('.item');
const currentAccordion = currentItem.closest('.accordion');
const isCloseOthers = !currentItem.classList.contains('open');
if (isCloseOthers) {
currentAccordion
.querySelectorAll('.item')
.forEach(item => {
if (item !== currentItem) {
item.classList.remove('open');
}
});
}
currentItem.classList.toggle('open');
}
function init() {
document
.querySelectorAll('.accordion-icon')
.forEach(elmNode =>
elmNode.addEventListener('click', handleAccordionItemStates)
);
}
init();
p { margin: 0; }
svg {
width 1em;
height: 1em;
transition: transform .3s ease-in;
}
.item { margin-bottom: 10px; }
.item p { float: left; margin-right: 10px; }
.item svg { float: right; margin-right: 50px; }
.hidden-box {
clear: both;
overflow: hidden;
padding-top: 5px;
transition: max-height .6s ease-in-out;
max-height: 0;
}
.item.open .hidden-box { max-height: 900px; }
.item.open svg { transform: rotate(180deg); }
<div class="accordion">
<div class="item">
<p class="number">01</p>
<p class="text">lorem ipsum</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et,
tempore repudiandae. Minima, cupiditate totam nihil laborum rem sit,
est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
<div class="item">
<p class="number">02</p>
<p class="text">accusantium quos</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et,
tempore repudiandae. Minima, cupiditate totam nihil laborum rem sit,
est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
<div class="item">
<p class="number">03</p>
<p class="text">cupiditate totam</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et,
tempore repudiandae. Minima, cupiditate totam nihil laborum rem sit,
est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
</div>
我看到 class 被主动添加到第一个元素的控制台中,但仅限于第一个元素。事件侦听器绑定到 svg 按钮。 Class 'open' 把 'hidden-block' display 变成 display: block;在项目容器中
const faqDropDown = document.querySelector(".accordion-icon");
const faqContainer = document.querySelector(".item");
faqDropDown.addEventListener("click", function() {
faqContainer.classList.toggle("open");
});
.item { margin-bottom: 10px; }
p { margin: 0; }
svg { width 1em; height: 1em; margin: 10px; }
<div class="item">
<p class="number">01</p>
<p class="text">lorem ipsum ist?</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
Et, tempore repudiandae. Minima, cupiditate totam nihil
laborum rem sit, est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
<div class="item">
<p class="number">02</p>
<p class="text">lorem ipsum ist?</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
Et, tempore repudiandae. Minima, cupiditate totam nihil
laborum rem sit, est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
你的问题是你正在使用 querySelector
它将 return 它遇到的第一个对象,这意味着它将 return 只有第一个项目 .item
.
为了对带有 class 的多个项目应用一些更改(我想你有多个 class="item"
),你需要使用 querySelectorAll
,这将 return具有 class item
.
下面我给你留下了一个例子,说明如何使用 querySelectorAll
然后遍历每个节点,然后应用你想要的更改。
注意:如果您查看代码,html 是我制作的,只是为了证明它有效(它将所有项目更改为红色)。 javascript 部分是更改为对所有项目进行正确更改的部分。只需将其复制粘贴到您的代码中即可。
const faqDropDown = document.querySelector(".accordion-icon");
const faqContainers = document.querySelectorAll(".item");
faqDropDown.addEventListener("click", function() {
faqContainers.forEach(faqContainer => {
faqContainer.classList.toggle("open");
})
});
.open {
color: red;
}
<button class="accordion-icon">
toggle open
</button>
<div class="item">
item1
</div>
<div class="item">
item2
</div>
<div class="item">
item3
</div>
<div class="item">
item4
</div>
OP 需要处理手风琴所有项目的状态。因此,对于提供的示例,必须为每个项目的 svg 图标注册一个事件处理程序。
处理程序不仅需要处理项目的切换状态,还需要检测和处理关闭所有其他项目的情况...
function handleAccordionItemStates({ currentTarget }) {
const currentItem = currentTarget.closest('.item');
const currentAccordion = currentItem.closest('.accordion');
const isCloseOthers = !currentItem.classList.contains('open');
if (isCloseOthers) {
currentAccordion
.querySelectorAll('.item')
.forEach(item => {
if (item !== currentItem) {
item.classList.remove('open');
}
});
}
currentItem.classList.toggle('open');
}
function init() {
document
.querySelectorAll('.accordion-icon')
.forEach(elmNode =>
elmNode.addEventListener('click', handleAccordionItemStates)
);
}
init();
p { margin: 0; }
svg {
width 1em;
height: 1em;
transition: transform .3s ease-in;
}
.item { margin-bottom: 10px; }
.item p { float: left; margin-right: 10px; }
.item svg { float: right; margin-right: 50px; }
.hidden-box {
clear: both;
overflow: hidden;
padding-top: 5px;
transition: max-height .6s ease-in-out;
max-height: 0;
}
.item.open .hidden-box { max-height: 900px; }
.item.open svg { transform: rotate(180deg); }
<div class="accordion">
<div class="item">
<p class="number">01</p>
<p class="text">lorem ipsum</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et,
tempore repudiandae. Minima, cupiditate totam nihil laborum rem sit,
est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
<div class="item">
<p class="number">02</p>
<p class="text">accusantium quos</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et,
tempore repudiandae. Minima, cupiditate totam nihil laborum rem sit,
est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
<div class="item">
<p class="number">03</p>
<p class="text">cupiditate totam</p>
<svg
xmlns="http://www.w3.org/2000/svg"
class="accordion-icon"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 9l-7 7-7-7"
/>
</svg>
<div class="hidden-box">
<p>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et,
tempore repudiandae. Minima, cupiditate totam nihil laborum rem sit,
est, ea et quaerat hic accusantium quos.
</p>
</div>
</div>
</div>