Evgenij Reznik
Evgenij Reznik

Reputation: 18614

Menu should disappear when clicked somewhere else

I have a div which should be visible, whenever a button is clicked. It's like a menu. Afterwards, it should disappear (toggle), when the button is clicked again or when the user clicks somewhere else on the page (whole body).

In my current approach, the menu constantly toggles, so both functions (see below) are being triggered.

$("#b1").click(function() {
  $("#menu").toggle("slide");
});

$("body").click(function() {
  if ($("#menu").is(":visible")) {
    $("#menu").toggle("slide");
  }
});

How should I improve my code, so that the menu only disappears when the button is clicked again or when the user clicks somewhere else?

Here is a fiddle.

Upvotes: 1

Views: 1907

Answers (7)

Jitendra Patel
Jitendra Patel

Reputation: 54

You have to do following changes.

$(document).ready(function() {
    $("#b1").click(function(e) {
        $("#menu").slideToggle();
        e.stopPropagation();
    });
    $(document).click(function(e) {
        if (!$(e.target).is('#menu, #menu *')) {
           $("#menu").slideUp();
        }
    });
});

Upvotes: 0

Arun CM
Arun CM

Reputation: 3435

I think this code will solve your issue. You can use e.target property to find whether user clicked on button or outside button. When user click on button b1 it enters both b1 click event and body click event. So if in order to find where the user is clicked you can use event.target property.

  1. Clicking the button will toggle the menu visibility.
  2. Clicking outside the button will close the menu if it is opened.

     $("#b1").click(function() {
        $("#menu").toggle("slide");
        $("#b1").text() == "hide menu" ? $("#b1").text("show menu") : $("#b1").text("hide menu");
    });
    
    $("body").click(function(e) {
      if (!$(e.target).is("#b1") && $("#menu").is(":visible")) {
        $("#menu").slideUp();
      } 
      else {
        e.preventDefault();
      }
    });
    

Working fiddle

Upvotes: 0

Preet Singh
Preet Singh

Reputation: 1861

Try this.

    $("#b1").click(function() {
event.stopPropagation();
  $("#menu").toggle("slide");
});

$("body").click(function() {
if(!$(event.target).closest('#menu').length){
if ($("#menu").is(":visible")) {
    $("#menu").toggle("slide");
  }
}

});

Upvotes: 0

Joey Etamity
Joey Etamity

Reputation: 866

Use $(window) to attach the event, then you can close the menu anywhere.

$("#b1").click(function() {
  $("#menu").toggle("slide");
   return false;
});

$(window).click(function() {
  if ($("#menu").is(":visible")) {
    $("#menu").toggle("slide");
  }
});

Check demo: https://jsfiddle.net/wru8mvxt/5/

Upvotes: 2

eisbehr
eisbehr

Reputation: 12452

You can use e.target and check whenever it's not the menu or the button which got clicked. Otherwise the menu closed even on the button click or on a click inside.

$("#b1").click(function() {
    $("#menu").slideDown();
});

$("body").click(function(e) {
    if (!$(e.target).is("#b1") && $("#menu").is(":visible")) {
        $("#menu").slideUp();
    } else {
        e.preventDefault();
    }
});

If you want the menu to stay even on click inside, just add && !$(e.target).is("#menu") to the if condition.

Working example.

Upvotes: 2

Haresh Vidja
Haresh Vidja

Reputation: 8496

I think your code looks good.. I see one problem when you click on menu it will be hide.

$("#b1").click(function() {
  $("#menu").toggle("slide");
  return false; // prevent to pass click event to body
});

$("body").click(function() {
  if ($("#menu").is(":visible")) {
    $("#menu").toggle("slide");
  }
});

$("#menu").click(function(e){
    e.preventDefault();
    return false;
});

Upvotes: 1

Jonathan Ben Avraham
Jonathan Ben Avraham

Reputation: 56

Use something like this:

$(document).mouseup(function (e)
{
    var container = $("YOUR CONTAINER SELECTOR");

    if (!container.is(e.target) // if the target of the click isn't the container...
        && container.has(e.target).length === 0) // ... nor a descendant of the container
    {
        container.hide();
    }
});

Upvotes: 0

Related Questions