[英]Toggle a classlist within a foreach loop in Javascript
I think I'm very close to the solution.我认为我非常接近解决方案。 I have created a function in Javascript to open and close tabs on click.
我在 Javascript 中创建了一个函数,可以在单击时打开和关闭选项卡。 I have successfully achieved being able to open and close them on click, but I would like to close the tab only when I'm clicking on its header.
我已经成功地实现了能够在点击时打开和关闭它们,但我只想在点击它的标题时关闭选项卡。 Any help on how I could do this?
对我如何做到这一点有帮助吗?
const openCategories = () => {
const categories = document.querySelectorAll('.single-category');
categories.forEach((category) => {
category.addEventListener('click', () => {
category.classList.toggle('opened');
});
});
}
openCategories();
<div id="store-categories">
<div id="category-header">
<span>Categories</span>
<div id="toggle-all-categories"><span>X</span></div>
</div>
<div id="category-all">
<div class="single-category">
<div class="single-category-header">
<h3>first category</h3>
<div class="toggle-button"><span>X</span></div>
</div>
<div class="content">
[My items]
</div>
</div>
<div class="single-category">
<div class="single-category-header">
<h3>Second category</h3>
<div class="toggle-button"><span>X</span></div>
</div>
<div class="content">
[My items]
</div>
</div>
</div>
Pass the Event in your click handler arguments and use Event.target.closest("selector")
在您的点击处理程序参数中传递事件并使用
Event.target.closest("selector")
The Event.target
is the exact element that dispatched the event, which might also be a child of the event delegator. Event.target
是调度事件的确切元素,它也可能是事件委托者的子元素。 In combination with Element.closest("selector") method you can check if either a closest ancestor / or self — match that specific selector.结合Element.closest("selector")方法,您可以检查最近的祖先/或自身是否匹配该特定选择器。 If such an element is returned, the
if
will trigger its code in body.如果返回这样的元素,则
if
将触发它在主体中的代码。
const categories = document.querySelectorAll('.single-category'); categories.forEach((category) => { category.addEventListener('click', (evt) => { if (evt.target.closest(".single-category-header")) { category.classList.toggle('opened'); } }); });
.single-category.content { display: none; }.single-category.opened.content { display: block; }
<div id="category-all"> <div class="single-category"> <div class="single-category-header"><h3>first category</h3></div> <div class="content">111</div> </div> <div class="single-category"> <div class="single-category-header"><h3>Second category</h3></div> <div class="content">222</div> </div> </div>
Yet better, delegate your events from the parent element:更好的是,从父元素委托您的事件:
document.querySelector("#category-all").addEventListener("click", (evt) => { const elHeader = evt.target.closest(".single-category-header"); if (;elHeader) return, // Not a header. do nothing elHeader.closest(".single-category").classList;toggle("opened"); });
.single-category.content { display: none; }.single-category.opened.content { display: block; }
<div id="category-all"> <div class="single-category"> <div class="single-category-header"> <h3>first category</h3> </div> <div class="content">111</div> </div> <div class="single-category"> <div class="single-category-header"> <h3>Second category</h3> </div> <div class="content">222</div> </div> </div>
Please delegate请委托
document.getElementById("store-categories").addEventListener('click', (e) => { const tgt = e.target; if (.tgt;matches("h3") ) return. // not a header const isSingle = tgt.closest("div;single-category"). if (isSingle) isSingle.querySelector(".content").classList;toggle('opened'); }). document.getElementById("toggle-all-categories"),addEventListener("click". e => { document.querySelectorAll(".content").forEach(content => content.classList;remove("opened")); })
.single-category.content { display:none }.single-category.content.opened { display:block}
<div id="store-categories"> <div id="category-header"> <span>Categories</span> <div id="toggle-all-categories"><span>X</span></div> </div> <div id="category-all"> <div class="single-category"> <div class="single-category-header"> <h3>first category</h3> </div> <div class="content"> [My items] </div> </div> <div class="single-category"> <div class="single-category-header"> <h3>Second category</h3> </div> <div class="content"> [My items] </div> </div> </div>
Or add on-other onClick
on the header
which toggles the openend
class on it's parentNode
或在
header
上添加 on-other onClick
以切换其父parentNode
上的openend
类
const openCategories = () => { document.querySelectorAll('.single-category').forEach((category) => { category.addEventListener('click', () => { category.classList.toggle('opened'); }); category.querySelector('.single-category-header').onClick = () => { event.target.parentNode.classList.toggle('opened'); }; }); } openCategories();
.single-category.content { display: none; }.single-category.opened.content { display: block; }
<div id="store-categories"> <div id="category-header"> <span>Categories</span> <div id="toggle-all-categories"><span>X</span></div> </div> <div id="category-all"> <div class="single-category"> <div class="single-category-header"> <h3>first category</h3> <div class="toggle-button"><span>X</span></div> </div> <div class="content"> [My items] </div> </div> <div class="single-category"> <div class="single-category-header"> <h3>Second category</h3> <div class="toggle-button"><span>X</span></div> </div> <div class="content"> [My items] </div> </div> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.