使用VanillaJS中的数据属性添加/删除类



正如本线程的标题所示,我正试图使用普通javascript中的数据属性将类添加到div中。然而,我不确定我是否会以最有效的方式来做这件事。

下面我添加了一些基本的HTML和javascript。如果有人能帮我填空,我将不胜感激。

var selector_mastmenu = document.getElementById("menu");
selector_mastmenu.addEventListener('click', function(event) {
if(event.target.classList.contains("has-child")) {
// Remove class `show` from all `menu__panel` divs.
// Find `menu__panel` with matching `data-menu-id` and add class `show`.
}
if(event.target.classList.contains("panel__back")) {
// Remove class `show` from all `menu__panel` divs.
// Find `parent-menu-id` of `menu__panel` add class `show` to `menu-id`.
}
});
#menu .menu__panel {
display: none;
}
#menu .menu__panel.show {
display: block;
}
<div id="menu">
<div class="menu__panel" data-menu-id="2_1" data-parent-menu-id="1">
<button class="panel__back" type="button">Return to Main Menu</button>
<ul class="panel__menu">
<li><a href="#">Second Level Menu Item</a></li>
<li><a href="#">Second Level Menu Item</a></li>
<li><a href="#">Second Level Menu Item</a></li>
</ul>
</div>
<div class="menu__panel show" data-menu-id="1">
<ul class="panel__menu">
<li><a href="#" class="has-child" data-menu-id="2_1">Menu Item</a></li>
</ul>
</div>
</div>

当前使用事件处理程序函数的方式会有问题。如何使用css设置样式以及在哪里使用单击可能不一致。目标元素可以是li标签或a标签。

下面是一个不更改html的工作示例。然而,如果我要用myslef来做这件事,我会更明确地使用您的点击处理程序,这样我就不需要在我的示例中使用parentNode之类的东西来遍历dom。如果你可以把数据属性放在按钮本身,为什么要遍历dom?

var hasChildElements = document.querySelectorAll('.has-child');
var menuPanelElements = document.querySelectorAll('.menu__panel');
var panelBackElements = document.querySelectorAll('.panel__back');
hasChildElements.forEach(el => {
el.addEventListener('click', showMenu)
})
panelBackElements.forEach(el => {
el.addEventListener('click', hideMenu)
})
function showMenu(event) {
var menuId = event.currentTarget.getAttribute('data-menu-id')
var menuPanelEl = document.querySelector(`div[data-menu-id="${menuId}"]`)
// Remove class `show` from all `menu__panel` divs.
menuPanelElements.forEach(el => {
el.classList.remove('show')
})
// Find `menu__panel` with matching `data-menu-id` and add class `show`.
menuPanelEl.classList.add('show')
}
function hideMenu(event) {
// Remove class `show` from all `menu__panel` divs.
menuPanelElements.forEach(el => {
el.classList.remove('show')
})
// Find `parent-menu-id` of `menu__panel` add class `show` to `menu-id`.
var menuId = document.querySelector('.panel__back').parentNode.getAttribute('data-parent-menu-id');
var parentMenu = document.querySelector(`div[data-menu-id="${menuId}"]`)
parentMenu.classList.add('show')
}
#menu .menu__panel {
display: none;
}
#menu .menu__panel.show {
display: block;
}
<div id="menu">
<div class="menu__panel" data-menu-id="2_1" data-parent-menu-id="1">
<button class="panel__back" type="button">Return to Main Menu</button>
<ul class="panel__menu">
<li><a href="#">Second Level Menu Item</a></li>
<li><a href="#">Second Level Menu Item</a></li>
<li><a href="#">Second Level Menu Item</a></li>
</ul>
</div>
<div class="menu__panel show" data-menu-id="1">
<ul class="panel__menu">
<li><a href="#" class="has-child" data-menu-id="2_1">Menu Item</a></li>
</ul>
</div>
</div>

这正是document.querySelectorAll构建的目的。它接受CSS类型选择器,并返回节点列表中的每个匹配元素,节点列表是一个可以迭代的类似数组的对象。例如,如果您正在查找类为menu__panel的每个对象,则需要

document.querySelectorAll('.menu__panel') // note the . before the class, just like CSS
.forEach(panel => {
panel.classList.add('plain-string-class-name'); // Adds plain-string-class-name to your class='' attribute in your HTML element
panel.classList.remove('plain-string-class-name'); // Removes plain-string-class-name from your class='' attribute in your HTML element. Does not error if plain-string-class-name does not exist.
});

最新更新