1

I have the following DOM structure :

<div onclick="function">
<element1 />
<element2 />
<element3 />
....
</div>

When I click on one any of the elements, the event.target is that element.

I want to always get the div as the event.target. Is there any way to stop the children from firing events ?

Note : This question is not a duplicate of this question. As what is asked in that question is exactly the other way.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Arian
  • 7,397
  • 21
  • 89
  • 177
  • Possible duplicate of [How do I prevent a parent's onclick event from firing when a child anchor is clicked?](http://stackoverflow.com/questions/1369035/how-do-i-prevent-a-parents-onclick-event-from-firing-when-a-child-anchor-is-cli) –  Feb 13 '16 at 05:00
  • @noob : I want the parent to catch it and the children not to catch. It's exactly the reverse. – Arian Feb 13 '16 at 05:04
  • It falls into same category. `Event Bubbling` –  Feb 13 '16 at 05:06

3 Answers3

3

If you always want the element that the event listener is attached to, then access the currentTarget property on the event object, event.currentTarget, instead of event.target.

The currentTarget property is the element that the event listener is currently attached to (which in your case would be the div with the onclick attribute).

<div onclick="clickHandler(event)"></div>
function clickHandler(event) {
  console.log('Event is attached to: ', event.currentTarget);
  console.log('The element clicked was: ', event.target);
}

In addition, if you pass the this keyword as a parameter, it would also refer to that element as well. You can use the .call() method in order to set the value of this in the function callback.

Update your onclick attribute to the following:

<div onclick="clickHandler.call(this, event)"></div>

And then your function's this keyword would refer to that div element and event would be passed as the first parameter:

function clickHandler(event) {
  console.log('Event is attached to: ', event.currentTarget);
  console.log('The element clicked was: ', event.target);
  console.log('"this" refers to: ', this);
}

Example demonstrating this:

div { border: 1px solid; height: 200px; width: 200px; }
<script>
function clickHandler(event) {
  console.log('Event is attached to: ', event.currentTarget);
  console.log('The element clicked was: ', event.target);
  console.log('"this" refers to: ', this);
}
</script>

<div onclick="clickHandler.call(this, event)">
  <span>'event.currentTarget' is the div</span>
  <span>'this' is also the div</span>
</div>

Is there any way to stop the children from firing events?

You could check if event.target is event.currentTarget.

In the snippet below, the if statement will be true when clicking outside of the children elements and it will be false when clicking the children elements directly:

function clickHandler(event) {
  if (event.target === event.currentTarget) {
    // ...
  }
}

Basic example:

div { border: 1px solid; height: 200px; width: 200px; }
<script>
function clickHandler(event) {
  console.log(event.target === event.currentTarget);
}
</script>

<div onclick="clickHandler(event)">
  <span>Click outside of a span</span>
  <span>Another span</span>
</div>
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • It looks like that there's a problem here. If I click on element1. Then then it doesn't pass the if and it won't be caught at all. right ? – Arian Feb 13 '16 at 20:07
  • @ArianHosseinzadeh I updated my answer. I hope that clears it up for you. Let me know if you have any questions. – Josh Crozier Feb 13 '16 at 20:26
1

You can pass container div with this inside your handler, will return f:

<div id="f" onclick="f(this)">f
  <div id="1">1</div>
  <div id="2">2</div>
  <div id="3">3</div>
</div>

function f(el) {
   alert(el.id)
}

Demo - Fiddle

Nikolay Ermakov
  • 5,031
  • 2
  • 11
  • 18
0

The children will fire the events. But if there's no function for those events, it will go to the parent.

You can stop event propagation to the the parent objects. But it's different in different browsers. I wrote a function to try to stop event propagation in all browsers. You call it from your javascript function that caught the event. Also, return false; in your function that caught the event.

function cancelEvent(e)
{
  e = e ? e : window.event;
  if(e.stopPropagation)
    e.stopPropagation();
  if(e.preventDefault)
    e.preventDefault();
  e.cancelBubble = true;
  e.cancel = true;
  e.returnValue = false;
  return false;
}
Russell Hankins
  • 1,196
  • 9
  • 17
  • If I stop propagation, then the event won't be caught , right ? but I want the parent to "catch" it. – Arian Feb 13 '16 at 05:05