19

I get an Uncaught TypeError: Illegal invocation for both versions of this attempt to put down an EventListener: (I get the error when the listener should be added, not when I click on the target)

ronan.addEventListener("click", alert, false);

addEventListener.apply(ronan, ["click", alert, false]);

ronan is a div element that is returned successfully by the console so I don't think that's the problem. Any ideas why I get this error? I read this thread and I couldn't figure it out from that.

12
  • maybe I should have waited til the morning to submit this Commented Aug 27, 2011 at 8:28
  • 1
    It might be the alert... native function. Does a blank function(){} work in its place? Commented Aug 27, 2011 at 8:29
  • @Artur Sapek Are you absolutely certain ronan is an HTMLDivElement? If so, can you post the code sets its value? Also, it would be nice if you could give a link to a demo page. By the way, which morning are talking about? It's currently morning in Europe and early in the morning in South America. Commented Aug 27, 2011 at 8:33
  • Also shouldn't the second line be ronan.addEventListener.apply(... instead of just addEventListener.apply(...? Commented Aug 27, 2011 at 8:36
  • 1
    You're all wrong about the second second line using apply - it should be HTMLElement.prototype.addEventListener.apply(ronan, [function () { }]);. Commented Aug 27, 2011 at 9:52

1 Answer 1

31

You need to wrap alert in a function. This will work:

ronan.addEventListener("click", function() { alert('Hi'); }, false);

Here's a fiddle for proof. Using alert alone doesn't work because when a listener is executed the value of this within that function is set to the object on which it is listening. For example, if you set a listener on ronan, within that listener this === ronan. This presents a problem for alert because that function expects this to be equal to window. You can work around this (no pun intended) by wrapping the function in another function or by binding it to whatever it expects this to be:

document.body.addEventListener('click', alert.bind(window), false);

Don't forget that in IE < 9 you need to use attachEvent rather than addEventListener.


A note on using apply/call with addEventListener

Your second attempt won't work because you're trying to apply your arguments to window.addEventListener, as opposed to HTMLElement.prototype.addEventListener, which is a different function altogether:

// This won't work
addEventListener.apply(ronan, ["click", alert.bind(window), false]);

// This will work
HTMLElement.prototype.addEventListener.apply(ronan, ['click', alert.bind(window), false]);
Sign up to request clarification or add additional context in comments.

1 Comment

Oh, word, you're right. I'm in fact not even using the prototype object, just the base, but your method still worked without the prototype part. I probably should have been aware of bind() since my JS is so focused on the DOM. Thanks a lot for your time!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.