子菜单无法正常工作

时间:2017-10-29 16:37:31

标签: javascript html css

我的子菜单有问题。子菜单会对点击作出反应,但我遇到问题,我点击子菜单<li>,内容被删除,我不想要这个。并且有任何错误,它写了这个错误“Uncaught TypeError:无法读取属性'classList'的null”。

可以帮助我吗?

/* Added .main class to parent <ul>
|| By adding the eventListener to the
|| parent of multiple clickable nodes
|| and using e.target property to find
|| the exact node actually clicked, we
|| have just needed the <ul> to listen
|| rather than 3 separate <li>
|| This is part of Event Delagation
*/
var main = document.querySelector('.main');

main.addEventListener('click', accordion, false);

function accordion(e) {
  // Stop <a> from jumping
  e.preventDefault();

  /* Gather all .dropdown-menu to a NodeList
  || then covert it to an array
  */
  var dropArray = Array.from(document.querySelectorAll('.dropdown-menu'));

  /* if the clicked node (e.target) is NOT the
  || node listening for event (e.currentTarget
  || ul.main) then...
  */
  if (e.target !== e.currentTarget) {

    /* Assign e.target to var
    || Find tgr next sibling (.dropdown-menu)
    || Iterate through dropArray wth a
    || for...of loop
    || Remove .show and add .hide on
    || each .dropdown-menu in dropArray
    || Then add .show and remove .hide
    || on tgt
    || Finally stop the click event from
    || bubbling, thereby preventing anything
    || else from being triggered.
    */
    var tgr = e.target;
    var tgt = tgr.nextElementSibling;
    for (let drop of dropArray) {
      drop.classList.remove('show');
      drop.classList.add('hide');
    }
    tgt.classList.add('show');
    tgt.classList.remove('hide');
  }
  e.stopPropagation();
}
ul {
  list-style: none
}

.dropdown a {
  text-decoration: none;
}

.dropdown [data-toggle="dropdown"] {
  position: relative;
  display: block;
  color: black;
  padding: 10px;
}

.dropdown .dropdown-menu {
  max-height: 0;
  overflow: hidden;
}

.dropdown .dropdown-menu li {
  padding: 0;
}

.dropdown .dropdown-menu li a {
  display: block;
  padding: 10px 10px;
}

.dropdown .show {
  display: block;
  max-height: 9999px;
  margin-left: 50px;
}

.dropdown .hide {
  max-height: 0;
}
<div class="container">
  <ul class='main'>
    <li class="dropdown">
      <a href="#" data-toggle="dropdown">First Menu</a>
      <ul class="dropdown-menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" data-toggle="dropdown">Second Menu</a>
      <ul class="dropdown-menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" data-toggle="dropdown">Third Menu </a>
      <ul class="dropdown-menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </li>
  </ul>
</div>

2 个答案:

答案 0 :(得分:1)

这是因为当您点击树叶时,'tgt'最终会变为null。您应该检查这一点以避免错误:

if (tgt) {
    for (let drop of dropArray) {
      drop.classList.remove('show');
      drop.classList.add('hide');
    }
    tgt.classList.add('show');
    tgt.classList.remove('hide');
}

答案 1 :(得分:0)

如果您不希望在选择子项目后关闭子菜单:

function accordion(e) {
  e.preventDefault();    
  if (e.target.tagName === 'A' && e.target !== e.currentTarget) { 
    var dropArray = Array.from(document.querySelectorAll('.dropdown-menu'));
    var tgt = e.target.nextElementSibling;
    if(tgt) {
      for (let drop of dropArray) {
        drop.classList.remove('show');
      }
      tgt.classList.add('show');
      tgt.classList.remove('hide');
    }
  }
  e.stopPropagation();
}

这也修复了“无法读取属性'classList'的null”错误。