点击锚标签时隐藏导航(Vanilla JavaScript)
我有一个在小屏幕上显示的导航。我的目标是每次单击导航中的锚点标签时隐藏该导航。 到目前为止,我尝试了多种选择,但似乎都没有用。我认为真正的问题是我不知道如何选择菜单中的所有锚点标签。我正在寻找的解决方案必须是纯 JS。提前谢谢您。
<nav id="mySidenav" class="sidenav">
<a href="#about">About</a>
<a href="#services" onclick="closeNav();">Services</a>
<a href="#contact">Contact</a>
</nav>
.sidenav {
width: 0;
}
.sidenav.mobile-only {
width:250px;
}
function closeNav() {
myNav.classList.remove("mobile-only");
}
选项 1
var anchorTags = document.querySelectorAll('a')
anchorTags.addEventListener('click', closeNav(), false);
** Uncaught TypeError: anchorTags.addEventListener is not a function
选项 2
var anchorTags = document.getElementsByTagName("a")
anchorTags.addEventListener('click', closeNav());
**Uncaught TypeError: anchorTags.addEventListener is not a function
选项 3
var anchorTags = document.querySelector("mobile-only a");
for (var x = 0; x < anchorTags.length; x++) {
anchorTags[x].addEventListener("click", function() {
closeNav();
});
};
**Uncaught TypeError: Cannot read property 'length' of null
我发现的唯一解决方案是内联添加函数,但我确信一定有更好的解决方案。
<a href="#about" onclick="closeNav();">About</a>
<a href="#services" onclick="closeNav();">Services</a>
<a href="#contact" onclick="closeNav();">Portofolio</a>
后期编辑: 选项 4:获胜者(有比这更好的解决方案,如下所示。谢谢大家)
var anchorTags = document.getElementById("mySidenav").childNodes;
for (var x = 0; x < anchorTags.length; x++) {
anchorTags[x].addEventListener("click", function() {
closeNav();
});
};
感谢大家的回复,我终于明白问题出在哪里了。我尝试了你们所有的解决方案,它们都运行良好。
我们将采用选项 3,因为它最接近解决方案。
您应该使用
document.querySelectorAll('nav a')
或更好的
document.querySelectorAll('.sidenav a')
。这将为您提供与我们的选择器匹配的所有元素的节点列表。之后,我们可以使用
forEach
循环遍历每个节点并绑定我们的点击事件。
document.querySelectorAll('.sidenav a').forEach(function(a) {
a.addEventListener('click', closeNav);
});
请注意,我使用了
closeNav
而不是
closeNav()
-
()
很重要!使用
()
将尝试立即调用该函数,而不是将该函数分配为事件的处理程序。
在选项 1 中,运行
querySelectorAll
后返回的是
nodeList
,类似于数组。您无法将事件侦听器添加到列表本身,您需要将侦听器添加到列表中的每个项目,类似于您在选项 3 中尝试执行的操作。在选项 2 中,这是同样的问题,但这次使用的是
HTMLCollection
。在选项 3 中,您执行的是
querySelector
,而不是
querySelectorAll
,后者仅返回与选择器匹配的第一个元素。因此如果您尝试使用
querySelectorAll
的选项 3,它应该可以工作。
当您使用
getElementsByTagName
时,它返回的是一个 Node 集合,而不是 HTMLElement,因此您需要循环它以向每个元素添加事件侦听器
var anchorTags = document.getElementsByTagName("a");
[...anchorTags].map(elem => elem.addEventListener('click', closeNav));
与
querySelector
相同,它返回一个 HTMLElement(只有一个),如果您希望它们全部使用
querySelectorAll
,您需要向它传递一个 CSS 选择器
var anchorTags = document.querySelector("a.mobile-only");
[...anchorTags].map(elem => elem.addEventListener('click', closeNav));
我使用数组展开
[...arraish_element]
为 Node Collection 提供真实数组的所有方法,并能够在那里使用 map,或者您只需使用 for 和 nodecollection 的长度即可