3

I have this setup

<div onclick="SomeEvent">
    <input type=checkbox value=1>1
    <input type=checkbox value=2>2
    <input type=checkbox value=3>3
</div>

The problem when the user click on the checkboxes I don't want the SomeEvent fired.

In the some event I do have the line
"event.stopPropagation();"
but that seems to do nothing at all.

John Soer
  • 551
  • 1
  • 7
  • 20
  • `SomeEvent` would have to be `SomeEvent()` if used in an inline event listener (which shouldn't be used). – connexo Dec 13 '21 at 15:38

2 Answers2

7

In the event bubbling model, the event propagation is from the inner elements to the outer elements.

This means that the event.stopPropagation(); should be in the inputs' events instead of the div.

<div onclick="SomeEvent">
  <input type=checkbox value=1 onclick="stopPropagation()">1
  <input type=checkbox value=2 onclick="stopPropagation()>2
  <input type=checkbox value=3 onclick="stopPropagation()>3
</div>

Now the Javascript code:

function stopPropagation() {
  //... do something.
  //stop propagation:
  if (!e) var e = window.event;
  e.cancelBubble = true; //IE
  if (e.stopPropagation) e.stopPropagation(); //other browsers
}

More info: http://www.quirksmode.org/js/events_order.html

EDIT: The above was a quick way to show how the bubbling model works, but a better answer to solve this problem using JQuery would be:

<div id="mydiv">
  <input type="checkbox" value="1" /> 1
  <input type="checkbox" value="2" /> 2
  <input type="checkbox" value="3" /> 3
</div>

Now the Javascript code:

$('#mydiv').click(function(e) {
  //do something
});

$('#mydiv input').click(function(e) {
  //stop propagation:
  if (!e) var e = window.event;
  e.cancelBubble = true; //IE
  if (e.stopPropagation) e.stopPropagation(); //other browsers
});
connexo
  • 53,704
  • 14
  • 91
  • 128
Felipe Brahm
  • 3,162
  • 1
  • 28
  • 42
  • I don't like that i have to add code to the checkbox to prevent the click from happening. – John Soer May 11 '11 at 23:58
  • This was just a quick example, but if you are using JQuery the right way to do this would be to use something like $('#element1 input').click(stopPropagation()); I'll update my answer. – Felipe Brahm May 12 '11 at 00:15
5

Change the inline onclick to this:

onclick="SomeEvent(this, event)"

Then in SomeEvent, do this:

function SomeEvent( el, event ) {
    var target = event.srcElement || event.target;

    if( el === target ) {
        // run your code
    }
}

This will only fire the code when you click on the div element itself, instead of a descendant.

If there are other descendants that should fire the handler, then do this:

function SomeEvent( el, event ) {
    var target = event.srcElement || event.target;

    if( target.nodeName.toLowerCase() !== 'input' || !target.type || target.type !== 'checkbox' ) {
        // run your code
    }
}

This will fire the handler for any click except those on the checkboxes.

RightSaidFred
  • 11,209
  • 35
  • 35
  • I like the potential this has since I can limit each event to one method. However I am using jquery to attach the event. In the attached event the event.target.id and the event.srcElementid is always blank. The this.id returns the proper id. – John Soer May 11 '11 at 23:55