简体   繁体   中英

click outside DIV

<body>
    <div id="aaa">
       <div id="bbb">
       </div>
    </div>
</body>


$(#?????).click(function(){

     $('#bbb').hide();

})

http://jsfiddle.net/GkRY2/

What i must use if i want hide #bbb if user click outside box #bbb? But if i click on div #bbb then box is still visible - only outside.

 $('body').click(function(e){
       if( e.target.id == 'bbb' )
          { return true; }
       else
          { $('#bbb').hide(); }

 });

A note of explanation: There are a few ways to do this, either way we need to listen for a click on a parent element, weather it be a direct parent like #aaa or a distant parent like the body or the document . This way we can capture clicks that occur outside of #bbb .

Now that we have that we need the .hide to NOT occur if the user did click inside of #bbb . We can do this two ways

  1. Stop propagation if the user clicks on #bbb . This will make the click event not 'bubble' up to the parent. That way the click event never reaches the parent and so #bbb will not hide. I personally don't like this method because stop propagation will so ALL click events from bubbling, and you may have click events that you would like to bubble to a local parent and not a distant parent. Or you may have listeners delegated from a distant parent, which will stop working if click propagation is stopped.

  2. Check for the #bbb element in the parent listener. This is the method shown above. Basically this listens on a distant parent, and when a click occurs it checks to see if that click is on #bbb specifically. If it IS NOT on #bbb .hide is fired, otherwise it returns true, so other things that may be tied into the click event will continue working. I prefer this method for that reason alone, but secondarily its a-little bit more readable and understandable.

Finally the manner in which you check to see if the click originated at #bbb you have many options. Any will work, the pattern is the real meat of this thing.

http://jsfiddle.net/tpBq4/ //Modded from @Raminson who's answer is very similar.


New suggestion, leverage event bubbling without jQuery.

var isOutSide = true
    bbb       = documment.getElementById('bbb');
document.body.addEventListener('click', function(){
   if(!isOutSide){
       bbb.style.display = 'none';
   }
   isOutSide = true;
});

bbb.addEventListener('click', function(){
   isOutSide = false;
});

Catch the click event as it bubbles-up to the document element. When it hits the document element, hide the element. Then in a click event handler for the element, stop the propagation of the event so it doesn't reach the document element:

$(function () {
    $(document).on('click', function () {
        $('#bbb').hide();
    });
    $('#bbb').on('click', function (event) {
        event.stopPropagation();
    });
});

Here is a demo: http://jsfiddle.net/KVXNL/

Docs for event.stopPropagation() : http://api.jquery.com/event.stopPropagation/

I made a plugin that does this. It preserves the value for this where as these other solutions' this value will refer to document .

https://github.com/tylercrompton/clickOut

Use:

$('#bbb').clickOut(function () {
    $(this).hide();
});

You can use target property of the event object, try the following:

$(document).click(function(e) {
    if (e.target.id != 'bbb') { 
          $('#bbb').hide();
    }
})

DEMO

This will work

$("#aaa").click(function(){

     $('#bbb').hide();

});

$("#bbb").click(function(event){

    event.stopPropagation();
})​

Becouse bbb is inside the aaa the event will "bubbel up to aaa ". So you have to stop the bubbling by using the event.stopPropagation when bbb is clicked

http://jsfiddle.net/GkRY2/5/

OK

* this is none jquery. you can easly modify it to work with IE

first create helper method to facilitate codding don't get confused with JQuery $()

    function $g(element) {

    return document.getElementById(element);

    }

create our listener class

  function globalClickEventListener(obj){

    this.fire = function(event){
        obj.onOutSideClick(event);
        }
    }

let's say we need to capture every click on document body

so we need to create listeners array and initialize our work. This method will be called on load

      function initialize(){

    // $g('body') will return reference to our document body. parameter 'body' is the id of our document body

    $g('body').globalClickEventListeners = new Array();
    $g('body').addGlobalClickEventListener = function (listener)
    {
        $g('body').globalClickEventListeners.push(listener);

    }

    //  capture onclick event on document body and inform all listeners

    $g('body').onclick = function(event) {
        for(var i =0;i < $g('body').globalClickEventListeners.length; i++){
            $g('body').globalClickEventListeners[i].fire(event);
        }
    }

}

after initialization we create event listener and pass reference of the object that needs to know every clcik on our document

    function goListening(){

        var icanSeeEveryClick = $g('myid');
        var lsnr = new globalClickEventListener(icanSeeEveryClick);

       // add our listener to listeners array   

        $g('body').addGlobalClickEventListener(lsnr);

       // add event handling method to div   

        icanSeeEveryClick.onOutSideClick = function (event){
             alert('Element with id : ' + event.target.id + ' has been clicked');
        }

    }

* Take into account the document body height and width

* Remove event listeners when you don't need them

$(document).click(function(event) { 
    if(!$(event.target).closest('#elementId').length) {
        if($('#elementId').is(":visible")) {
            $('#elementId').hide('fast');
        }
    }        
})

Change the "#elementId" with your div.

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