12

How to get the ID of an element passed as (e)?

window.addEventListener('load', function(){ var tags = document.getElementsByClassName("tag"); for (i=0; i<tags.length; i++){ tags[i].addEventListener('mousedown', function(e){ tagClick(e) }, false); } }, false); function tagClick(e){ /* here I'm gonna need the event to cancel the bubble and the ID to work with it*/ alert('The id of the element you clicked: ' + [?object].id); [?object].className='newClass'; e.stopPropagation(); e.cancelBubble = true; } 

I need to get the element/object inside tagClick so I can change its properties

html:

<div class="tag"> <img src="/images/tags/sample.jpg"/> <label class="tagLabel">Sample</label> </div> 

See, the element with the event attached is the div, but ig gives me the image object instead when using e.srcElement.

6
  • Any reason why you're not using jQuery? All this headache can be written in one line of jQuery. Commented Jan 1, 2014 at 13:08
  • 1
    @ShadowWizard Because jQuery is bloody slow? In my project, I can write a delegated event handler in one line too because I created a very specific function to do the job. addDelegatedEvent(document.body,function(t) {return r.nodeName == "TAG";},"click",function(e) {alert(e.target.id);}); Commented Jan 1, 2014 at 13:10
  • 1
    @NiettheDarkAbsol what about browser compatibility? That's also major reason to use jQuery. Anyway let's not spam this question, there's chat for those things. :) Commented Jan 1, 2014 at 13:15
  • @ShadowWizard addDelegatedEvent does the browser compatibility for me, because I programmed it to ;) Commented Jan 1, 2014 at 13:20
  • @ShadowWizard When I'm done learning JavaScript then I'll use JQuery :) Commented Jan 1, 2014 at 13:22

3 Answers 3

20

When you bind an event listener with addEventListener, it's called with this referring to the element you bound the event on. So this.id will be the id of the element (if it has one).

alert('The id of the element you clicked: ' + this.id); 

But you're breaking that with this line:

tags[i].addEventListener('mousedown', function(e){ tagClick(e) }, false); 

...because you're putting an extra function in the middle, then calling tagClick without setting this. There's no need for that extra function, change that to:

tags[i].addEventListener('mousedown', tagClick, false); 

...so this doesn't get messed up. Or alternately if you prefer to have the extra function, ensure this is maintained using Function#call:

tags[i].addEventListener('mousedown', function(e){ tagClick.call(this, e) }, false); 

...but there's no reason to do that with the tagClick function shown.

The (standard) event object also has the properties target (which may not be the element you bound the event on, it may well be a descendant) and currentTarget (which will be the element you bound the event on). But this is convenient and reliable if you use addEventListener (or even attachEvent, on IE).

Sign up to request clarification or add additional context in comments.

10 Comments

@Azevedo: Oddly, I was just editing the answer because I noticed you did something odd in your addEventListener. See the update. :-) Sorry for missing that initially.
tags[i].addEventListener('mousedown', tagClick, false); seems to fit better. Works. Besides, it is already cancelling the bubble propagation [bacaused I cancelled the bubble propagation before it sticks?]
@Azevedo: I'm not following you, whether you put an extra function layer in doesn't relate to bubbling at all. Yes, you're cancelling bubbling, so once the event bubbles from the image to the element where you're hooking it, you're stopping it at that point.
The tags <div> are inside another <div> (background shader). Somehow, using tags[i].addEventListener('mousedown', tagClick, false); instead of tags[i].addEventListener('mousedown', function(e){ tagClick(e) }, false); I don't need to cancel the Bubbling.
@Azevedo Since you already had accepted great answer, let me add live examples ;) With Direct binding and With event delegation
|
6

You can get the target of the event with e.target.

However keep in mind that some browsers consider text nodes to be a target, so try something like this:

var t = e.target; while(t && !t.id) t = t.parentNode; if( t) { alert("You clicked element #"+t.id); } 

This will find the first element that actually has an ID.

Happy New Year!

EDIT: On second thought, if it's the "tag" element itself you want to refer to, just use this. In an event handler, this refers to the element that actually has the handler. Although in this case you'll need to change your handler to ('mousedown', tagClick, false)

Or better still:

document.body.addEventListener("mousedown",function(e) { var t = e.target; while(t && t.nodeName != "TAG") { // note, must be uppercase t = t.parentNode; } if( t) { alert("You clicked on #"+t.id); } },false); 

Fewer event handlers is always better.

5 Comments

for IE it's srcElement. (also see here)
When you directly bind events, instead of while(t && !t.id) t = t.parentNode;, why not simply use e.currentTarget?
@ShadowWizard IE also uses attachEvent. Since OP is only using addEventListener, I'm only using target.
@niet: check the HTML. The problem is there is an image clicked inside a DIV (wich is what I want). Instead, it gives me the image.
Neat, didn't notice that.
4
document.getElementById("body").addEventListener("mousedown", function(e){ console.log(e.target.id); }); 

enjoy.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.