JohnG
JohnG

Reputation: 497

Excluding an element with jquery

Is it possible to exclude an element from a jquery click event? A simplified version of my issue is this:

CSS

.outerbox{
 height:100px;
 width:100px;
 background-color:red;
 position:relative;
 }

 .innerbox{
 height:50px;
 width:50px;
 background-color:yellow;
 margin:auto;
 position: absolute;
 top: 25%;
 left: 25%;
 }

HTML

 <div class="outerbox">
   <div class="innerbox"></div>
 </div>

JQUERY

 $(".outerbox").not(".innerbox").click(function() {
   alert( "Red has been clicked, but not the yellow area" );
 });

My not selector does not work though. I've tried $(".outerbox:not('.innerbox')") too, to no effect. Any ideas how I could do this?

Upvotes: 0

Views: 62

Answers (5)

Roamer-1888
Roamer-1888

Reputation: 19288

This is all about event bubbling, not a jQuery selector issue.

The click event has an e.eventPhase property, which indicates which phase of the event flow is currently being evaluated.

e.eventPhase takes the value:

  • Event.NONE: 0
  • Event.CAPTURING_PHASE: 1
  • Event.AT_TARGET: 2
  • Event.BUBBLING_PHASE: 3

In the event handler, on clicking the red square you should see e.eventPhase == 2, and on clicking the yellow square you should see e.eventPhase == 3.

So, either of the following will give the desired effect :

$(".outerbox").click(function(e) {
    if(e.eventPhase !== Event.BUBBLING_PHASE) {
        // here, clicks on any of the target's child elements are excluded.
        alert( "Red has been clicked, but not the yellow area");
    }
});

or

$(".outerbox").click(function(e) {
    if(e.eventPhase === Event.AT_TARGET) {
        // here, clicks on any of the target's child elements are excluded.
        alert( "Red has been clicked, but not the yellow area");
    }
});

Thus, you can write your code to filter out clicks on any number of descendent elements, without even knowing their classes/ids.

DEMO

Upvotes: 0

Dejan.S
Dejan.S

Reputation: 19118

Unless you are arent gone do anything with the innerbox click I would go with checking the target.

demo on jsfiddle

$(".outerbox").on('click', function(e) {
   if (e.target.classList.contains('innerbox')) {
        return false;
   }

   // your code here
});

Upvotes: 0

Rana Ghosh
Rana Ghosh

Reputation: 4674

Just replace your JS code with this::

$(".outerbox").click(function(event) {
    if($(event.target).attr('class') == 'outerbox')
        alert( "Red has been clicked, but not the yellow area" );
 });

Upvotes: 0

David
David

Reputation: 218807

You can't stop the element from having a click event, but you can capture that click event and stop it from propagating through the DOM. So you would have your outer click event handler as normal:

$(".outerbox").click(function() {
  alert( "Red has been clicked, but not the yellow area" );
});

And also add a click handler for the "inner" element which does nothing more than cancel the event:

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

Example

Upvotes: 4

kapantzak
kapantzak

Reputation: 11750

You can use the target attribute form the event raised:

$(".outerbox").on('click', function(event) {
   var trg = $(event.target);
   if (trg.hasClass('innerbox')) {
      // Inner was clicked
   }
})

Upvotes: 0

Related Questions