简体   繁体   English

有人可以告诉我我的下拉菜单javascript代码有什么问题吗

[英]Can someone tell me what's wrong with my dropdown menu javascript code

I've been learning Javascript and as a bit of practice, thought i'd create myself a dropdown navigation menu, that works on a 'click' rather than hover. 我一直在学习Javascript,并作为一种实践,以为我会为自己创建一个下拉导航菜单,该菜单可在“单击”而不是悬停时使用。 I've created the code below (which doesn't work) and i was wondering if someone could explain why so i can see where i've gone wrong. 我创建了下面的代码(不起作用),我想知道是否有人可以解释为什么,这样我就可以看到我哪里出了问题。

I can get the dropdown to open, but when i added the code to close the dropdown, the dropdown menu doesn't even open. 我可以打开下拉菜单,但是当我添加代码以关闭下拉菜单时,下拉菜单甚至无法打开。

I'm hoping someone can point me in the right direction so i can see where i'm going wrong and i can avoid such issues in the future 我希望有人可以指出正确的方向,这样我就能知道我要去哪里了,以后我可以避免此类问题

 (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> 

As requested, the CSS is as follows 根据要求,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;
}

`` ``

I think it can happen because at first you are adding nav-open class than you are checking is it exist if yes you are adding event to window(window still can catch this event) and deleting this class so nothing should happen. 我认为这是可能发生的,因为首先要添加的是nav-open类,而不是要检查的是否存在(如果是),则要将事件添加到window(窗口仍可以捕获此事件)并删除此类,因此什么也不应该发生。 Try to add event.stopPropagation() under event.preventDefault() 尝试在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');
          }
        };
      };
    });
  });


})();```

Consider using event delegation instead. 考虑改为使用事件委托。 When anywhere on the page is clicked, run an event listener. 单击页面上的任何位置时,请运行事件侦听器。 If the clicked target is not inside a LI, remove the .nav-open from the existing element with .nav-open , if there is one. 如果单击的目标不在LI内,则使用.nav-open从现有元素中删除.nav-open (如果存在)。 Otherwise, if the clicked target was the <a> (a descendant of the outer .menu-item-has-children ), navigate to its second child ( .children[1] ) and add the class to it: 否则,如果单击的目标是<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> 

maybe like so, code should be self explanatory 也许像这样,代码应该是自我解释的

 // 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> 

This is a wroking demo 这是一个令人讨厌的演示

 (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> 

The first mistake on your code was declaring this 您代码上的第一个错误是声明了这一点

let subMenu = document.querySelector('.sub-menu');

this always will be the first subMenu, so I just removed it. 这始终是第一个子菜单,因此我将其删除。 If you want to get the subMenu of every element you should do something like this: 如果要获取每个元素的subMenu,则应执行以下操作:

btn.querySelector('.sub-menu')

So now It will get the sub menu for every element inside the forEach you already did. 现在,它将为您已经完成的forEach中的每个元素提供子菜单。


To close the menu on document click I just made an event listener on document click which will remove the class nav-open from any of the sub menus. 要关闭文档单击上的菜单,我只是在文档单击上创建了一个事件侦听器,它将从任何子菜单中删除nav-open类。

document.addEventListener("click", function(){
    subMenus.forEach(function(ele) {
        ele.classList.remove('nav-open');
    });
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JavaScript:有人可以告诉我我的代码出了什么问题吗? - JavaScript: Can someone tell me what's going wrong with my code? 有人可以告诉我此javascript有什么问题吗? - Can someone tell me what's wrong with this javascript? 有人可以告诉我我的代码有什么问题吗? 返回正确的世纪 - Can someone tell me what's wrong with my code? Return correct century 有人请告诉我$ .parseJSON有什么问题[javascript / jquery] - Someone please tell me what is wrong with my $.parseJSON [javascript / jquery] 需要检查用户输入是否为数字。 代码无法正常工作。 有人可以告诉我怎么了吗? - Need to check whether user input is a number. Code is not working as intended. Can someone tell me what's wrong? 有人可以帮我弄清楚我的代码有什么问题吗? 它将 RNA 序列翻译成蛋白质 - Can someone help me figure out what's wrong with my code?. It translates RNA sequences into proteins 有人可以告诉我我的 Redux 状态有什么问题吗? - Can someone show me what's wrong with my Redux state? 您能告诉我这段JavaScript代码有什么问题吗? - Can you tell me what is wrong with this javascript code? 谁能告诉我这个switch语句(javascript)怎么了? - Can anyone tell me what's wrong with this switch statement (javascript)? 谁能告诉我我的代码有什么问题 - Can anyone tell me what is wrong in my code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM