簡體   English   中英

有人可以告訴我我的下拉菜單javascript代碼有什么問題嗎

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM