106

I need to have a handler on the calling object of onclick event.

<a href="123.com" onclick="click123(event);">link</a>

<script>
  function click123(event) {
    //i need <a> so i can manipulate it with Jquery
  }
</script>

I want to do this without the use of $().click or $().live of jQuery but with the method described above.

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Kostas Konstantinidis
  • 13,347
  • 10
  • 48
  • 61

5 Answers5

192

pass in this in the inline click handler

<a href="123.com" onclick="click123(this);">link</a>

or use event.target in the function (according to the W3C DOM Level 2 Event model)

function click123(event)
{
    var a = event.target;
}

But of course, IE is different, so the vanilla JavaScript way of handling this is

function doSomething(e) {
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
        targ = targ.parentNode;
}

or less verbose

function doSomething(e) {

    e = e || window.event;
    var targ = e.target || e.srcElement || e;
    if (targ.nodeType == 3) targ = targ.parentNode; // defeat Safari bug
}

where e is the event object that is passed to the function in browsers other than IE.

If you're using jQuery though, I would strongly encourage unobtrusive JavaScript and use jQuery to bind event handlers to elements.

rsc
  • 10,348
  • 5
  • 39
  • 36
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • 3
    `if (!e) var e = window.event;` is somewhat redundant — `e` is already declared, why do it again? `if` can also be avoided altogether in favor of shorter ternary — `e = e || window.event`. Ditto for `e.target` — those 3 lines are easily replaceable with — `var target = e.target || e.srcElement` ;) – kangax Oct 12 '09 at 13:08
  • @kangax - I wouldn't say that `e= e || window.event` is a ternary operator as there are not three arguments but two, it's a `logical-or/default` operator - http://javascript.crockford.com/survey.html. But I take the point, it does look neater and I usually use it. I simply pasted the code from the linked article, but will up my answer now :) – Russ Cam Oct 12 '09 at 13:28
  • @Russ Cam Sigh... Next time I'll make sure to drink coffee in the morning before leaving comments :) – kangax Oct 12 '09 at 14:46
  • 1
    @kangax - No problem, you had a valid point for succinctness :) – Russ Cam Oct 12 '09 at 15:02
  • Could somebody give details about the "Safari bug", especially to which version this applies and where/if this is "fixed"eventually? – Axel Heider Nov 14 '17 at 16:24
  • The second part of the answer seems to be lifted directly from: https://www.quirksmode.org/js/events_properties.html (the way it was linked is not clear in saying that) – insaner Jun 10 '20 at 07:48
  • I use Visual Studio Code to write Javascript and it is telling me that 'event' is deprecated. – Rodent Oct 30 '21 at 05:39
18

I think the best way is to use currentTarget property instead of target property.

The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM. It always refers to the element to which the event handler has been attached, as opposed to Event.target, which identifies the element on which the event occurred.


For example:

<a href="#"><span class="icon"></span> blah blah</a>

Javascript:

a.addEventListener('click', e => {
    e.currentTarget; // always returns "a" element
    e.target; // may return "a" or "span"
})
Az.Youness
  • 2,167
  • 1
  • 24
  • 33
  • it's not. currentTarget doesn't exist on IE and Firefox. You need to fallback to srcElement for these browsers. In case your element doesn't have children you can safely use target always. Use e.currentTarget || e.srcElement only for divs and stuff that have children below. – Vlatko Vlahek Feb 23 '19 at 14:00
  • 2
    No It's well supported !, currentTarget it's not supported only in (<= IE8), https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget#Browser_compatibility – Az.Youness Mar 22 '19 at 17:46
  • Thanks for the head's up! Might be that React had an issue in one of the versions then, as this is where I reproduced the issue. – Vlatko Vlahek Mar 22 '19 at 21:46
  • 4
    this answer identifies a major gotcha with the accepted answer (your target could be any child of the onclick parent, and not necessarily the parent element iteslf) and should have more upvotes. – kpup Aug 09 '19 at 17:32
  • its null on chrome for me – Directory Nov 18 '20 at 02:54
  • nvm apparently it needs to be stored as a variable, itll always be null if the entire event is console.log – Directory Nov 18 '20 at 06:16
  • `currentTarget` ever is null on mozilla firefox 88.0.1. – e-info128 Jun 02 '21 at 23:09
11

The easiest way is to pass this to the click123 function or you can also do something like this(cross-browser):

function click123(e){
  e = e || window.event;
  var src = e.target || e.srcElement;
  //src element is the eventsource
}
jerjer
  • 8,694
  • 30
  • 36
7

http://docs.jquery.com/Events/jQuery.Event

Try with event.target

Contains the DOM element that issued the event. This can be the element that registered for the event or a child of it.

Svetlozar Angelov
  • 21,214
  • 6
  • 62
  • 67
6

The thing with your method is that you clutter your HTML with javascript. If you put your javascript in an external file you can access your HTML unobtrusive and this is much neater.

Lateron you can expand your code with addEventListener/attackEvent(IE) to prevent memory leaks.

This is without jQuery

<a href="123.com" id="elementid">link</a>

window.onload = function () {
  var el = document.getElementById('elementid');
  el.onclick = function (e) {
    var ev = e || window.event;
    // here u can use this or el as the HTML node
  }
}

You say you want to manipulate it with jQuery. So you can use jQuery. Than it is even better to do it like this:

// this is the window.onload startup of your JS as in my previous example. The difference is 
// that you can add multiple onload functions
$(function () {
  $('a#elementid').bind('click', function (e) {
    // "this" points to the <a> element
    // "e" points to the event object
  });
});
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
Robert Cabri
  • 3,821
  • 1
  • 20
  • 17