[英]Can someone tell me what's wrong with my dropdown menu javascript code
我一直在學習Javascript,並作為一種實踐,以為我會為自己創建一個下拉導航菜單,該菜單可在“單擊”而不是懸停時使用。 我創建了下面的代碼(不起作用),我想知道是否有人可以解釋為什么,這樣我就可以看到我哪里出了問題。
我可以打開下拉菜單,但是當我添加代碼以關閉下拉菜單時,下拉菜單甚至無法打開。
我希望有人可以指出正確的方向,這樣我就能知道我要去哪里了,以后我可以避免此類問題
(function() { let menuHeader = document.querySelectorAll('.menu-item-has-children'); let subMenu = document.querySelector('.sub-menu'); menuHeader.forEach(function(btn) { btn.addEventListener('click', function(event) { event.preventDefault(); subMenu.classList.add('nav-open'); // Close if anywhere on screen aprt form menu is clicked if (subMenu.classList.contains('nav-open')) { window.onclick = function(event) { if (!event.target.classList.contains('sub-menu')) { subMenu.classList.remove('nav-open'); } }; }; }); }); })();
<nav class="main-nav"> <ul> <li><a href="" title="Home">Home</a></li> <li class="menu-item-has-children"><a href="#" title="What We Do">What We Do</a> <ul class="sub-menu"> <li><a href="" title="">Page 1</a></li> <li><a href="" title="">Page 2</a></li> <li><a href="" title="">Page 3</a></li> <li><a href="" title="">Page 4</a></li> <li><a href="" title=" ">Page 5</a></li> <li><a href="" title="">Page 6</a></li> </ul> </li> <li class="menu-item-has-children"><a href="#" title="Our Work">Our Work</a> <ul class="sub-menu"> <li><a href="" title="">Portfolio 1</a></li> <li><a href="" title="">Portfolio 2</a></li> <li><a href="" title="">Portfolio 3</a></li> <li><a href="" title="">Portfolio 4</a></li> <li><a href="" title="">Portfolio 5</a></li> </ul> </li> <li><a href="" title="">Contact</a></li> </ul> </nav>
根據要求,CSS如下
.main-nav ul > li {
display: inline;
position: relative;
}
.main-nav ul li a {
display: inline-block;
font-family: bebas-neue, sans-serif;
font-style: normal;
font-weight: 400;
text-decoration: none;
color: #333;
font-size: 1.3em;
padding: 0.5em 0.8em 0.8em 0.8em;
transition: background 0.2s linear;
}
.main-nav ul li a:hover {
background: #00a492;
color: #fff;
}
.main-nav ul li a:not(:only-child):after {
content: '\25bc';
font-size: 0.6em;
position: relative;
top: -4px;
left: 2px;
}
/* Second Level of Navigation */
.main-nav ul li ul {
width: 250px;
position: absolute;
top: 160%;
left: 0;
background: #00a492;
}
.main-nav ul li ul li a {
display: block;
}
.sub-menu {
display: none;
}
.nav-open {
display: block;
}
.slicknav_menu {
display:none;
}
.highlight-btn {
background: #00a492 !important;
color: #fff !important;
}
``
我認為這是可能發生的,因為首先要添加的是nav-open
類,而不是要檢查的是否存在(如果是),則要將事件添加到window(窗口仍可以捕獲此事件)並刪除此類,因此什么也不應該發生。 嘗試在event.preventDefault()
下添加event.stopPropagation()
event.preventDefault()
(function() {
let menuHeader = document.querySelectorAll('.menu-item-has-children');
let subMenu = document.querySelector('.sub-menu');
menuHeader.forEach(function(btn) {
btn.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation()
subMenu.classList.add('nav-open');
// Close if anywhere on screen aprt form menu is clicked
if (subMenu.classList.contains('nav-open')) {
window.onclick = function(event) {
if (!event.target.classList.contains('sub-menu')) {
subMenu.classList.remove('nav-open');
}
};
};
});
});
})();```
考慮改為使用事件委托。 單擊頁面上的任何位置時,請運行事件偵聽器。 如果單擊的目標不在LI內,則使用.nav-open
從現有元素中刪除.nav-open
(如果存在)。 否則,如果單擊的目標是<a>
(外部.menu-item-has-children
的后代),請導航至其第二個子項( .children[1]
)並將類添加至其中:
function closeOpenNav() { const currentOpen = document.querySelector('.nav-open'); if (currentOpen) { currentOpen.classList.remove('nav-open'); } } window.addEventListener('click', (event) => { const li = event.target.closest('.menu-item-has-children'); if (!li) { // Close if anywhere on screen aprt form menu is clicked console.log('closing'); closeOpenNav(); return; } if (event.target.parentElement !== li) { // The clicked element is a descendant of a `.nav-open` // so, don't do anything return; } event.preventDefault(); closeOpenNav(); const thisSubMenu = li.children[1]; thisSubMenu.classList.add('nav-open'); });
.sub-menu { display: none; } .nav-open { display: block; }
<nav class="main-nav"> <ul> <li><a href="" title="Home">Home</a></li> <li class="menu-item-has-children"><a href="#" title="What We Do">What We Do</a> <ul class="sub-menu"> <li><a href="" title="">Page 1</a></li> <li><a href="" title="">Page 2</a></li> <li><a href="" title="">Page 3</a></li> <li><a href="" title="">Page 4</a></li> <li><a href="" title=" ">Page 5</a></li> <li><a href="" title="">Page 6</a></li> </ul> </li> <li class="menu-item-has-children"><a href="#" title="Our Work">Our Work</a> <ul class="sub-menu"> <li><a href="" title="">Portfolio 1</a></li> <li><a href="" title="">Portfolio 2</a></li> <li><a href="" title="">Portfolio 3</a></li> <li><a href="" title="">Portfolio 4</a></li> <li><a href="" title="">Portfolio 5</a></li> </ul> </li> <li><a href="" title="">Contact</a></li> </ul> </nav>
也許像這樣,代碼應該是自我解釋的
// Dropdown Menu (function(){ let menuHeader = document.querySelectorAll('.menu-item-has-children'); menuHeader.forEach(function(btn){ btn.addEventListener('click', function(event){ event.preventDefault(); if(this.classList.contains('nav-open')) { return this.classList.remove('nav-open'); } var openNavPoints = document.querySelectorAll('.menu-item-has-children.nav-open'); if(openNavPoints.length >= 1) { [...openNavPoints].forEach(function(openNavPoint) { openNavPoint.classList.remove('nav-open'); }); } this.classList.add('nav-open'); }); }); })();
.menu-item-has-children .sub-menu { display: none; } .menu-item-has-children.nav-open .sub-menu { display: block; }
<nav class="main-nav"> <ul> <li><a href="" title="Home">Home</a></li> <li class="menu-item-has-children"><a href="#" title="What We Do">What We Do</a> <ul class="sub-menu"> <li><a href="" title="">Page 1</a></li> <li><a href="" title="">Page 2</a></li> <li><a href="" title="">Page 3</a></li> <li><a href="" title="">Page 4</a></li> <li><a href="" title=" ">Page 5</a></li> <li><a href="" title="">Page 6</a></li> </ul></li> <li class="menu-item-has-children"><a href="#" title="Our Work">Our Work</a> <ul class="sub-menu"> <li><a href="" title="">Portfolio 1</a></li> <li><a href="" title="">Portfolio 2</a></li> <li><a href="" title="">Portfolio 3</a></li> <li><a href="" title="">Portfolio 4</a></li> <li><a href="" title="">Portfolio 5</a></li> </ul> </li> <li><a href="" title="">Contact</a></li> </ul> </nav>
這是一個令人討厭的演示
(function() { let menuHeader = document.querySelectorAll('.menu-item-has-children'); let subMenus = document.querySelectorAll('.sub-menu'); menuHeader.forEach(function(btn) { btn.querySelector('a').addEventListener('click', function(event) { event.preventDefault(); event.stopImmediatePropagation(); closeAllMenus(); btn.querySelector('.sub-menu').classList.add('nav-open'); }); }); document.addEventListener("click", function(){ closeAllMenus(); }); function closeAllMenus(){ subMenus.forEach(function(ele) { ele.classList.remove('nav-open'); }); } })();
.sub-menu{ display: none; } .sub-menu.nav-open{ display: block; }
<nav class="main-nav"> <ul> <li><a href="" title="Home">Home</a></li> <li class="menu-item-has-children"> <a href="#" title="What We Do">What We Do</a> <ul class="sub-menu"> <li><a href="" title="">Page 1</a></li> <li><a href="" title="">Page 2</a></li> <li><a href="" title="">Page 3</a></li> <li><a href="" title="">Page 4</a></li> <li><a href="" title=" ">Page 5</a></li> <li><a href="" title="">Page 6</a></li> </ul> </li> <li class="menu-item-has-children"><a href="#" title="Our Work">Our Work</a> <ul class="sub-menu"> <li><a href="" title="">Portfolio 1</a></li> <li><a href="" title="">Portfolio 2</a></li> <li><a href="" title="">Portfolio 3</a></li> <li><a href="" title="">Portfolio 4</a></li> <li><a href="" title="">Portfolio 5</a></li> </ul> </li> <li><a href="" title="">Contact</a></li> </ul> </nav>
您代碼上的第一個錯誤是聲明了這一點
let subMenu = document.querySelector('.sub-menu');
這始終是第一個子菜單,因此我將其刪除。 如果要獲取每個元素的subMenu,則應執行以下操作:
btn.querySelector('.sub-menu')
現在,它將為您已經完成的forEach中的每個元素提供子菜單。
要關閉文檔單擊上的菜單,我只是在文檔單擊上創建了一個事件偵聽器,它將從任何子菜單中刪除nav-open
類。
document.addEventListener("click", function(){
subMenus.forEach(function(ele) {
ele.classList.remove('nav-open');
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.