[英]Show/Hide children in menu when clicking on parent (with pure javascript)
我對 JavaScript 有基本的了解,我正在嘗試創建一個菜單,其中:
這是我到目前為止所擁有的,我知道這遠非正確。 我在網上找到了一堆 jQuery 解決方案,但我想要它純 JavaScript & CSS。
注意:我還需要將使用的類和 ID 的數量保持在最低限度,因為我希望能夠將其與 WordPress 菜單結構一起使用。 但是,如果我需要為每個有孩子的父母手動添加一個“父母”class,那就沒問題了。
我的 JavaScript:
var menuParents = document.querySelectorAll("#my-menu .parent");
menuParents.forEach(menuParent => {
document.querySelector("#my-menu .parent").addEventListener("click", ToggleMenu);
function ToggleMenu() {
document.querySelector("#my-menu .parent ul").style.display = 'block';
}
});
我的 CSS:
#my-menu .parent ul {display: none;}
最后,我的 HTML:
<ul id="my-menu">
<li>Standard Item</li>
<li>Standard Item</li>
<li class="parent">Item with children
<ul>
<li>child item</li>
<li>child item</li>
<li class="parent">child item with children
<li>second level child</li>
<li>second level child</li>
</li>
<li>child item</li>
<li>child item</li>
</ul>
</li>
<li>Standard Item</li>
<li>Standard Item</li>
<li class="parent">Item with children
<ul>
<li>child item</li>
<li>child item</li>
<li class="parent">child item with children
<li>second level child</li>
<li>second level child</li>
</li>
<li>child item</li>
<li>child item</li>
</ul>
</li>
<li>Standard Item</li>
<li>Standard Item</li>
</ul>
您需要使用forEach
中的特定元素,然后只需獲取它的firstElementChild
,並切換display
樣式:
const toggle = { block: 'none', none: 'block' } function ToggleMenu(event) { event.stopPropagation(); event.target.classList.toggle('active'); event.target.firstElementChild.style.display = toggle[event.target.firstElementChild.style.display] || 'block'; } var menuParents = document.querySelectorAll("#my-menu.parent"); menuParents.forEach(menuParent => { menuParent.addEventListener("click", ToggleMenu); })
#my-menu.parent ul {display: none;}.active { color: red }.active > * { color: black }
<ul id="my-menu"> <li>Standard Item</li> <li>Standard Item</li> <li class="parent">Item with children <ul> <li>child item</li> <li>child item</li> <li class="parent">child item with children <ul> <li>second level child</li> <li>second level child</li> </ul> </li> <li>child item</li> <li>child item</li> </ul> </li> <li>Standard Item</li> <li>Standard Item</li> <li class="parent">Item with children <ul> <li>child item</li> <li>child item</li> <li class="parent">child item with children <ul> <li>second level child</li> <li>second level child</li> </ul> </li> <li>child item</li> <li>child item</li> </ul> </li> <li>Standard Item</li> <li>Standard Item</li> </ul>
或沒有“父” class
const toggle = { block: 'none', none: 'block' } function ToggleMenu(event) { event.stopPropagation(); if (event.target.firstElementChild) { event.target.classList.toggle('active'); event.target.firstElementChild.style.display = toggle[event.target.firstElementChild.style.display] || 'block'; } } var menuParents = document.querySelectorAll("#my-menu li > ul"); menuParents.forEach(menuParent => { menuParent.parentElement.addEventListener("click", ToggleMenu); })
#my-menu li > ul {display: none;}.active { color: red }.active > * { color: black }
<ul id="my-menu"> <li>Standard Item</li> <li>Standard Item</li> <li>Item with children <ul> <li>child item</li> <li>child item</li> <li>child item with children <ul> <li>second level child</li> <li>second level child</li> </ul> </li> <li>child item</li> <li>child item</li> </ul> </li> <li>Standard Item</li> <li>Standard Item</li> <li>Item with children <ul> <li>child item</li> <li>child item</li> <li>child item with children <ul> <li>second level child</li> <li>second level child</li> </ul> </li> <li>child item</li> <li>child item</li> </ul> </li> <li>Standard Item</li> <li>Standard Item</li> </ul>
你的 HTML 有點錯誤:你父母里面的父母沒有ul
元素。
<ul id="my-menu">
<li>Standard Item</li>
<li>Standard Item</li>
<li class="parent">Item with children
<ul>
<li>child item</li>
<li>child item</li>
<li class="parent">child item with children
<!-- here -->
<ul>
<li>second level child</li>
<li>second level child</li>
</ul>
</li>
</ul>
</li>
<li>child item</li>
<li>child item</li>
<li>Standard Item</li>
<li>Standard Item</li>
<li class="parent">Item with children
<ul>
<li>child item</li>
<li>child item</li>
<li class="parent">child item with children
<!-- and here -->
<ul>
<li>second level child</li>
<li>second level child</li>
</ul>
</li>
</ul>
</li>
<li>child item</li>
<li>child item</li>
<li>Standard Item</li>
<li>Standard Item</li>
</ul>
JavaScript 明智,您的切換 function 實際上並沒有切換任何東西,或者它不會切換超過一次,無論如何。
另一個問題是,當您單擊父級的父級時,也會調用單擊處理程序,這段代碼也說明了這一點。
這里我使用了一個匿名的 function。 您不必這樣做,命名為 function 可以正常工作,但它不會弄亂您唯一的命名空間。
這也適用於任何級別的父母:附加的片段具有二級父母。
var menuParents = document.querySelectorAll("#my-menu .parent");
menuParents.forEach(
menuParent => {
menuParent.addEventListener(
"click",
// inline, anonymous function
// also accepts an event parameter
function (event) {
// check if the parent element was actually clicked (prevent parent of parent from toggling display)
if (event.target == this) {
// this == menuParent
// select ul from menuParent
var menuChild = this.querySelector("ul");
// toggle child menu display, based on it's current display
if (menuChild.style.display == "block") {
// here, you could also set the display to null, since your CSS sets the display to none anyway
menuChild.style.display = "none";
} else {
menuChild.style.display = "block";
}
}
}
);
}
);
在 Chrome 87.0.4280.88 上測試。
var menuParents = document.querySelectorAll("#my-menu.parent"); menuParents.forEach( menuParent => { menuParent.addEventListener( "click", // inline, anonymous function // also accepts an event parameter function (event) { if (event.target == this) { // this == menuParent // select ul from menuParent var menuChild = this.querySelector("ul"); // toggle child menu display, based on it's current display if (menuChild.style.display == "block") { // here, you could also set the display to null, since your CSS sets the display to none anyway menuChild.style.display = "none"; } else { menuChild.style.display = "block"; } } } ); } );
#my-menu.parent ul { padding-left: 16px; display: none; }
<ul id="my-menu"> <li>Standard Item</li> <li>Standard Item</li> <li class="parent">Item with children <ul> <li>child item</li> <li>child item</li> <li class="parent">child item with children <ul> <li>second level child</li> <li>second level child</li> <li class="parent">second level parent <ul> <li>third level child</li> <li>third level child</li> </ul> <li>second level child</li> <li>second level child</li> </ul> </li> <li>child item</li> <li>child item</li> </ul> </li> </li> <li>Standard Item</li> <li>Standard Item</li> <li class="parent">Item with children <ul> <li>child item</li> <li>child item</li> <li class="parent">child item with children <ul> <li>second level child</li> <li>second level child</li> <li class="parent">second level parent <ul> <li>third level child</li> <li>third level child</li> </ul> </li> <li>second level child</li> <li>second level child</li> </ul> </li> <li>child item</li> <li>child item</li> </ul> </li> <li>Standard Item</li> <li>Standard Item</li> </ul>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.