Mam pewne problemy z zastanawieniem, jak zamknąć div, klikając w dowolnym miejscu na ekranie.

Obecnie przełączam klasę "aktywną", aby wyświetlić uproszczenie Div, a następnie próbując usunięcie tej klasy, klikając na ciało:

$(document).ready(function () {

    $('.navbar a').click(function () {
        $(this).next('.navbar-dropdown').toggleClass('active');
    });

    $(body).click(function() {
        if($('.navbar-dropdown').hasClass('active')){
            $('.navbar-dropdown').removeClass('active');
        }
    });

});

<ul class="navbar">
    <li>
        <a href="#">Link</a>
        <div class="navbar-dropdown">
            Dropdown Content
        </div>
    </li>
</ul>

Jednak są one sprzeczne ze sobą, więc jak tylko klasa jest przełączona, kliknięcie "Ciało" przełącza go w tym samym czasie. Spędziłem trochę czasu na patrzenie tutaj i kilka razy natkną się na tę metodę:

$(document.body).click( function() {
    closeMenu();
});

$(".dialog").click( function(e) {
    e.stopPropagation();
});

Jednak wszelkie próby skonfigurowania tego do pracy poprawnie wydawały się spadać na głuche uszy!

1
SJOSE 1 marzec 2019, 18:23

2 odpowiedzi

Najlepsza odpowiedź

Wydarzenie Click z Navbar pasuje do ciała, więc obu zdarzeń ogień. stopPropagation() jest jednym ze sposobów, aby temu zapobiec, ale musisz to zrobić w obsłudze zdarzeń Link Navbar, więc zatrzymuje się, że szczególne wydarzenie; Nie w osobnej obsługi zdarzeń, jak go miałeś.

Inną zmianą, którą można rozważyć, jest przypisanie tylko nadwozia Click Click, gdy go potrzebujesz, zamiast strzelać cały czas - Utwórz ten program obsługi wewnątrz kliknięcia Navbar's Click, i dezaktywuj go ponownie, gdy jest używany:

$(document).ready(function() {
  $('.navbar a').click(function(e) {
    var myDropdown = $(this).next('.navbar-dropdown');
    $('.navbar-dropdown.active').not(myDropdown).removeClass('active'); // close any other open dropdowns
    myDropdown.toggleClass('active'); // open this one
    $('body').click(function() {
      // no need for an if statement here, just use a selector that matches the active elements:
      $('.navbar-dropdown.active').removeClass('active');
      $('body').off('click'); // cancel the body's click handler when it's used
    });
    e.stopPropagation(); // prevent the navbar event from bubbling up to the body
  });
});
.active {
  color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="navbar">
  <li>
    <a href="#">Link</a>
    <div class="navbar-dropdown">
      Dropdown Content
    </div>
  </li>
    <li>
    <a href="#">Link 2</a>
    <div class="navbar-dropdown">
      Dropdown Content 2
    </div>
  </li>
    <li>
    <a href="#">Link 3</a>
    <div class="navbar-dropdown">
      Dropdown Content 3
    </div>
  </li>
</ul>

(Jeśli istnieje szansa, że możesz potrzebować więcej niż jednego osobnego kliknięcia na ciele, możesz przestrzegać zdarzeń, dzięki czemu możesz kontrolować, który się wyłączy:

$('body').on("click.myNamespace", function() {
  // do other stuff
  $('body').off("click.myNamespace")
})
2
Daniel Beck 1 marzec 2019, 18:17

Zrobiłem dokładną rzecz jako ty i to dla mnie działa. Czy jesteś pewien, że nie masz żadnych innych słuchaczy zdarzeń? A może z-indeks w menu przynoszący go pod innymi elementami?

$(document).click(function(e) {
  $(".dialog").text('closed')
});

$(".dialog").click(function(e) {
  e.target.innerText = 'open';
  e.stopPropagation();
});
.dialog {
  width: 200px;
  height: 200px;
  background: antiquewhite;
  text-align: center;
}
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
  <div class="dialog">open</div>
</body>

</html>
0
iacobalin 1 marzec 2019, 15:41