简体   繁体   中英

Use jQuery to click anywhere and remove 'active' class

I'm having some trouble figuring out how to close a div by clicking anywhere on the screen.

I'm currently toggling an 'active' class in order to display a drop down div, then attempting to remove that class by clicking on the body:

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

However they are conflicting with each other, so as soon as the class is toggled on, the 'body' click toggles it off at the same time. Have spent some time looking on here and came across this method a few times:

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

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

However any attempts to configure this to work correctly seemed to fall on deaf ears!

The click event from the navbar is bubbling up to the body, so both events fire. stopPropagation() is one way to prevent that, but you need to do it in the navbar link's event handler, so it stops that particular event; not in a separate event handler as you had it.

Another change you might consider making is to only assign the body click handler when you need it, instead of firing all the time -- create that handler inside the navbar's click handler, and deactivate it again when it's used:

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

(If there's a chance you might need more than one separate click event handler on the body, you can namespace the event so you can control which one you're turning off:

$('body').on("click.myNamespace", function() {
  // do other stuff
  $('body').off("click.myNamespace")
})

I did the exact thing as you and it works for me. Are you sure you don't have any other event listeners attached? Or maybe a z-index on the menu bringing it underneath other elements?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM