72

I have an onclick attribute on my link:

<a href="#" onclick="myFunc(1,2,3)">click</a>

That points to this event handler in JavaScript:

function myFunc(p1,p2,p3) {
    //need to refer to the current event object:
    alert(evt.type);        
}

Since the event object "evt" is not passed to a parameter, is it still possible to obtain this object?

I tried window.event and $(window.event), but both are undefined.

Any idea?

Web_Designer
  • 72,308
  • 93
  • 206
  • 262
LazNiko
  • 2,083
  • 3
  • 25
  • 39

4 Answers4

100

Since the event object "evt" is not passed from the parameter, is it still possible to obtain this object?

No, not reliably. IE and some other browsers make it available as window.event (not $(window.event)), but that's non-standard and not supported by all browsers (famously, Firefox does not).

You're better off passing the event object into the function:

<a href="#" onclick="myFunc(event, 1,2,3)">click</a>

That works even on non-IE browsers because they execute the code in a context that has an event variable (and works on IE because event resolves to window.event). I've tried it in IE6+, Firefox, Chrome, Safari, and Opera. Example: http://jsbin.com/iwifu4

But your best bet is to use modern event handling:

HTML:

<a href="#">click</a>

JavaScript using jQuery (since you're using jQuery):

$("selector_for_the_anchor").click(function(event) {
    // Call `myFunc`
    myFunc(1, 2, 3);

    // Use `event` here at the event handler level, for instance
    event.stopPropagation();
});

...or if you really want to pass event into myFunc:

$("selector_for_the_anchor").click(function(event) {
    myFunc(event, 1, 2, 3);
});

The selector can be anything that identifies the anchor. You have a very rich set to choose from (nearly all of CSS3, plus some). You could add an id or class to the anchor, but again, you have other choices. If you can use where it is in the document rather than adding something artificial, great.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 5
    Thanks for this explanation, this part of javascript has always confused me. The idea of this invisible, mystical "event" parameter being passed in from nowhere was never explained well to me. – Captain Hypertext Oct 30 '15 at 13:18
15

in IE you can get the event object by window.event in other browsers with no 'use strict' directive, it is possible to get by arguments.callee.caller.arguments[0].

function myFunc(p1, p2, p3) {
    var evt = window.event || arguments.callee.caller.arguments[0];
}
Web_Designer
  • 72,308
  • 93
  • 206
  • 262
otakustay
  • 11,817
  • 4
  • 39
  • 43
  • 1
    arguments.callee.caller.arguments is still expecting the event is passed as a parameter/argument. – Caspar Kleijne May 01 '11 at 15:46
  • This would not work. The function is explicitly being called from the event handler **without** the event parameter, so it cannot be accessed as an argument. – Pointy May 01 '11 at 15:47
  • 1
    I tested it on Chrome and it works, the Event object is an implicit argument for HTML inline event, and `arguments.callee.caller` is the HTML generated anonymous event handler function, its first argument is the Event object implicitly – otakustay May 01 '11 at 15:53
  • 6
    `arguments.callee.caller` is not universally supported, is massively slow in some implementations where it is supported, is a *really* bad idea, and is disallowed in strict mode. – T.J. Crowder May 01 '11 at 15:55
  • 1
    right, callee and caller are discouraged, but it is the only way to access the Event object when event handling code is placed inline with HTML, the best way is always register events unobstrutively using javascript :) – otakustay May 01 '11 at 15:59
  • @otakustay: *"...but it is the only way to access the Event object when event handling code is placed inline with HTML..."* No it isn't (see my answer). I think all of us responding agree, though, that it's best not to do that. :-) – T.J. Crowder May 01 '11 at 16:04
  • Ok @otakustay I see what you're up to here. It's icky but it would work :-) – Pointy May 01 '11 at 16:25
  • since I was often asked like **I cannot modify the HTML but can I ...** so I just provide a way that does not require any modification on original HTML, notice it's weird, discouraged and sometimes buggy:-) – otakustay May 01 '11 at 16:29
  • @otakustay Thx for this suggestion, arguments.callee.caller is really a new thing to me. – LazNiko May 03 '11 at 08:18
  • It's extremely hacky in any case. – John Dvorak Jan 11 '14 at 09:57
  • great solution @otakustay – Minesh Patel Jul 21 '16 at 06:07
  • `window.event` didn't work for me in Mozilla but `arguments.callee.caller` did. Not sure about its impact on browser performance but it works fine for me. – Bhagyesh Jain May 22 '17 at 11:21
4

Write your event handler declaration like this:

<a href="#" onclick="myFunc(event,1,2,3)">click</a>

Then your "myFunc()" function can access the event.

The string value of the "onclick" attribute is converted to a function in a way that's almost exactly the same as the browser (internally) calling the Function constructor:

theAnchor.onclick = new Function("event", theOnclickString);

(except in IE). However, because "event" is a global in IE (it's a window attribute), you'll be able to pass it to the function that way in any browser.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • tested in FF and you were right, it failed hard. Deleted the post before the deluge of downvotes came. Thanks for the heads up :) – JohnP May 01 '11 at 15:53
1

If you call your event handler on markup, as you're doing now, you can't (x-browser). But if you bind the click event with jquery, it's possible the following way:

Markup:

  <a href="#" id="link1" >click</a>

Javascript:

  $(document).ready(function(){
      $("#link1").click(clickWithEvent);  //Bind the click event to the link
  });
  function clickWithEvent(evt){
     myFunc('p1', 'p2', 'p3');
     function myFunc(p1,p2,p3){  //Defined as local function, but has access to evt
        alert(evt.type);        
     }
  }

Since the event ob

Edgar Villegas Alvarado
  • 18,204
  • 2
  • 42
  • 61
  • 1
    *"If you call your event handler on markup, as you're doing now, you can't (x-browser)."* Actually, you can (see my answer; that works in all major browsers and all minor ones I've ever tried -- IE6+, Firefox, Chrome, Safari, Opera...). But it's probably best not to. – T.J. Crowder May 01 '11 at 16:02
  • But in your solution, you are sending `event` as a parameter, and LazNiko's requirement is not to do it. There must be another way, but it's worthless since the asker is gone :S – Edgar Villegas Alvarado May 01 '11 at 16:20
  • One approach (using markup) indeed, would be to call `clickWithEvent` function from the markup, but, as we know, calling from markup is not the best way (and it'd be the same solution in the end). – Edgar Villegas Alvarado May 01 '11 at 16:28