daGrevis
daGrevis

Reputation: 21333

How to close element when click is made everywhere except on opened element?

I'm trying to make panel that opens when it's clicked on the button. I have the button, I have the panel. With click() event it does open. When that button is pressed again, it does close.

$('#button').click(function() {

    $('#panel').toggle();
});

I want to achieve that if user clicks everywhere except on #button or #panel, it does close too.

P.S. I tried something like this, but it's not the wanted behavior.

$('#button').mouseenter(function() {

    $('#panel').show();

}).mouseleave(function() {

    setTimeout(function() {
        $('#panel').hide();
    }, 2000);
});

Upvotes: 4

Views: 498

Answers (4)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 195982

A direct answer to your request would be

$('body').click(function(e)

   var starter = $(e.target);
   if ( starter.is('#button, #panel') || starter.closest('#panel').length > 0 ) return;

   setTimeout(function() {
       $('#panel').hide();
   }, 2000);

})

But seeing what you attempted to do with the mouseout you might consider this a better approach

$('#button').click(function() {

    $('#panel').show();

});

$('#panel').mousenter(function() {

    var closetimer = $(this).data('closetimer');  // retrieve the timer if it exists
    clearTimeout(closetimer); // and clear the timeout when we re-enter to cancel the closing

}).mouseleave(function() {

    var closetimer = setTimeout(function() {
        $('#panel').hide();
    }, 2000);

    $(this).data('closetimer', closetimer); // store the timer with the panel so we can cancel it if we need

});

Upvotes: 1

ShankarSangoli
ShankarSangoli

Reputation: 69905

Try this

$('#button').click(function(e) {

    $('#panel').toggle();
    e.stopPropagation();

});

$('#panel').click(function(e) {

    e.stopPropagation();

});

$(document.body).click(function(e) {
    if($('#panel').is(":visible")){
      $('#panel').hide();
    }
});

Upvotes: 3

epascarello
epascarello

Reputation: 207501

$(
    function(){
        $("#button").click( function(){ $("#panel").toggle(); } );
        $(document).click( function(e){
            var elm = jQuery(e.target);
            if(elm.is("#button") || elm.is("#panel") || elm.parents("#panel").length>0)return;
            $("#panel").hide();
        });
    }
);

Example

Checks to make sure that the element that was clicked [e.target] is not

  1. The button elm.is("#button")
  2. The panel elm.is("#panel")
  3. Any element in the panel elm.parents("#panel").length>0

Upvotes: 4

Spudley
Spudley

Reputation: 168655

Have an invisible element layered behind the panel, which takes up 100% of the screen (or page). This element would be given the click event that would close both itself any the panel.

This will also prevent the click to close the panel from triggering any other actions on the rest of the site.

If you wanted to, you could also make the layered element grey and semi-transparent, which would give you the effect of ghosting out the rest of the site while the panel is displayed. This effect is used quite often by Javascript popup box scripts, and you could do it virtually for free since you'd already be placing the full-screen element anyway; you'd just have to style it.

Upvotes: 0

Related Questions