выпадающий навигатор при наведении исчезает при перемещении над полем, javascript и css

#javascript #css

#javascript #css

Вопрос:

Мой UL для навигации имеет верхнее поле в 6,4 пикселя, поэтому его можно центрировать по вертикали, при перемещении мыши с родительского li на ul, который падает вниз, он исчезает при пересечении поля. Вот мой код, и внизу я добавлю то, что я пробовал.

css

 nav ul li > ul {
    flex-direction: column;
    display: flex;
    width: 100%;
    opacity: 0;
    transition: opacity 1s; 
}

.opacity1 {
    opacity: 1;
    transition: opacity 1s; 
}
 

javascript

 navInnerContainer.children[1].children[1].children[0].addEventListener("mouseover", () => {
      navParent.children[1].classList.add("opacity1");
});
navInnerContainer.children[1].children[1].addEventListener("mouseout", () => {
      navParent.children[1].classList.remove("opacity1");
});
 

HTML

  <div class="nav-inner-container">
            <div class="nav-logo">
                <p>Logo</p>
            </div>
       <ul>
           <li>
               <a href="#">Home</a>
           </li>
           <li class="nav-parent">
               <a href="#">Shop</a>
               <ul class="nav-child-ul">
                   <li><a href="#">Computers</a></li>
                   <li><a href="#">Phones</a></li>
                   <li><a href="#">Gaming</a></li>
                   <li><a href="#">Software Licenses</a></li>
                   <li><a href="#">Acessories</a></li>
               </ul>
           </li>
           <li>
               <a href="#">Cart
               <span class="cart-btn">
                   <i class="fa fa-shopping-cart"></i>
               
               <span class="cart-items">0</span>
               </span>
            </a>
           </li>
       </ul>
      </div> 
 

Вещи, которые я пробовал

 navInnerContainer.children[1].children[1].children[0].style.marginBottom.addEventListener("mouseover", () => {
      navParent.children[1].classList.add("opacity1");
});
 

^ вы не можете добавить прослушиватель событий к стилю, но что-то вроде этого было бы идеально.

 navInnerContainer.children[1].children[1].children[1].addEventListener("mouseover", () => {
      if (navInnerContainer.children[1].children[1].children[1].style.opacity > 0) {
        navParent.children[1].classList.add("opacity1");
      }
});
 

^ попытка поймать его до того, как он исчезнет .. не работает

 navParent.children[0].addEventListener("mouseover", () => {
      navParent.children[1].classList.add("opacity1");
      navParent.children[1].classList.add("mouseIsOverParent");
      setTimeout(function(){ 
        if (navChild.classList.contains("mouseIsOverChild") === false) {
           navParent.children[1].classList.remove("mouseIsOverParent");}   }, 3000);     
    });
navParent.addEventListener("mouseout", () => {
      navParent.children[1].classList.remove("opacity1");
    });
navChild.addEventListener("mouseover", () => {
  if (navParent.children[1].classList.contains("mouseIsOverParent")) {
      navParent.children[1].classList.add("mouseIsOverChild");
  } if (navParent.children[1].classList.contains("mouseIsOverChild")) {
     navParent.children[1].classList.add("opacity1");
  }
    });
navChild.addEventListener("mouseout", () => {
  navParent.children[1].classList.remove("mouseIsOverChild");
  navParent.children[1].classList.remove("opacity1");
});
 

^ это последнее, грязное, но наиболее функциональное, в конечном итоге оно застревает и начинает отображать выпадающий список при прохождении мыши, когда он должен оставаться невидимым.

извините, что в кодах беспорядок, я ценю любую помощь. в худшем случае я могу включить событие щелчка.

Ответ №1:

возможно, это поможет.

 const navInnerContainer = document.getElementsByClassName("nav-inner-container")[0];

[...document.querySelectorAll(".nav-inner-container>ul>li")].forEach(li => {
  if (li.childElementCount === 2) {
    li.addEventListener("mouseover", function() {
      this.querySelector(".nav-child-ul").classList.add("opacity1");
    });
    li.addEventListener("mouseout", function() {
      this.querySelector(".nav-child-ul").classList.remove("opacity1");
    });
  }
}); 
 ul li>ul {
  flex-direction: column;
  display: none;
  width: 100%;
  opacity: 0;
  transition: opacity 1s;
}

.opacity1 {
  display: flex;
    opacity: 1;
    animation-name: fadeInOpacity;
    animation-iteration-count: 1;
    animation-timing-function: ease-in;
    animation-duration: 1s;
}

@keyframes fadeInOpacity {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
} 
 <head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>

<body>
<div class="nav-inner-container">
  <div class="nav-logo">
    <p>Logo</p>
  </div>
  <ul>
    <li>
      <a href="#">Home</a>
    </li>
    <li class="nav-parent">
      <a href="#">Shop</a>
      <ul class="nav-child-ul">
        <li><a href="#">Computers</a></li>
        <li><a href="#">Phones</a></li>
        <li><a href="#">Gaming</a></li>
        <li><a href="#">Software Licenses</a></li>
        <li><a href="#">Acessories</a></li>
      </ul>
    </li>
    <li>
      <a href="#">Cart
        <span class="cart-btn">
          <i class="fa fa-shopping-cart"></i>

          <span class="cart-items">0</span>
        </span>
      </a>
    </li>
  </ul>
</div>

</body> 

Ответ №2:

Это плохая идея пытаться добавлять прослушиватели событий во внешнее пространство элемента. Вместо этого вы можете добавить оболочку вокруг своей навигации и добавить к ней отступы.

Итак, вы могли бы сделать

 <div class="nav-outer-container">
  <div class="nav-inner-container">
  /* Your nav code here */
  </div>
</div>
 

Ваш JS-код будет

 jQuery(".nav-outer-container").hover(function(){
  //do code
}, function(){
  //do code
});
 

Ваш код CSS будет

 .nav-outer-container { padding-top: 60px; }