Error in IE when manually calling event handler, given certain conditions
Preface
- Please note, I'm not looking for a code soluti开发者_如何学Con, but rather insight into why this may occur.
- The error occurs in IE (tested 7 & 8), but not Firefox, Chrome, Safari.
Description
When manually calling a function assigned to onclick
, IE with throw a Error: Object doesn't support this action
if all of the following conditions are met:
- You call the method directly via the element's
on[event]
property. - You do not use
.call()
or.apply()
. - You pass an argument (any argument, even
undefined
). - You attempt to assign the return value to a variable.
Violate any one of those rules, and the call succeeds.
The function itself appears to have nothing to do with it. An empty function gives the same result.
Code
var elem = document.getElementById('test'); // simple div element.
var result; // store result returned.
function test_func(){}; // function declaration.
// function expression behaves identically.
elem.onclick = test_func; // assign test_func to element's onclick.
// DIRECT CALL
test_func(); // works
test_func( true ); // works
result = test_func(); // works
result = test_func( true ); // works
// DIRECT CALL, CHANGING THE CONTEXT TO THE ELEMENT
test_func.call( elem ); // works
test_func.call( elem, true ); // works
result = test_func.call( elem ); // works
result = test_func.call( elem, true ); // works ******** (surprising)
// CALL VIA ELEMENT, USING .call() METHOD, CHANGING THE CONTEXT TO THE ELEMENT
elem.onclick.call( elem ); // works
elem.onclick.call( elem, true ); // works
result = elem.onclick.call( elem ); // works
result = elem.onclick.call( elem, true ); // works ******** ( very surprising)
// CALL VIA ELEMENT
elem.onclick(); // works
elem.onclick( true ); // works
result = elem.onclick(); // works
result = elem.onclick( true ); // Error: Object doesn't support this action
Summary
Again, I don't need a code solution. Rather I'm curious if anyone has insight into why IE is implemented this way.
Many thanks.
EDIT: To clarify one thing, nothing with the actual function seems to make any difference. Naming parameters, not naming them, returning the argument, returning a literal value, returning undefined, all of these have no effect.
This is likely because the function seems to never actually get called. As I noted in a comment below, the code leading up to this call runs fine, so it isn't a parsing issue either. But when the interpreter gets to this one, it sees:
Variable + AssignmentOperator + DOMElement + EventHandler + CallOperator + Argument
...and throws the Error. No manipulation I do seems to make any difference. A valid removal of any one of those, and the Error disappears.
If I place add a variable to the middle of it that stores the handler, then fire it from the variable it works.
var temp = elem.onclick;
result = temp( true ); // works
...but this shouldn't be much of a surprise, since it is effectively the same as the fourth version above.
As to "why" it was implemented this way, there's probably no answer from the outside. A good example is when former IE developer, the inventor of innerHTML, faces problems with innerHTML itself.
Asking why is also unnecessary because
- You don't often call event handlers with parameters explicitly
- You can work around the issue (as you stated in your question)
Another thing to note is that your analogy is too specific. The issue is not restricted to the assignment expression
, you can reproduce it with other types of expressions
:
undefined === elem.onclick( true )
typeof elem.onclick( true )
elem.onclick( true ) - 1
alert(elem.onclick( true ))
Have you tried using the instructions found here? He suggests using code like this:
var fireOnThis = document.getElementById('someID');
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent( 'click', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
fireOnThis.dispatchEvent(evObj);
Try some function that actually has one parameter and actually returns something. See if it produces an error too. It may have something to do with parameters and a function default return value. Try it and post the results back, please.
EDIT
If the function does not get called, the problem could be in the resolution of the property onclick. It may be somehow you are not actually calling your defined function, but the code finds some other build in IE object when you pass true as parameter. In any case this behavior is out of any specifications and so we may call it bug. Of those IE has plenty as you can see from my own questions.
IE 8 absolute positioned element outside its parent clipping problem
IE8 bottom:0 in position:absolute behaves like position:fixed
精彩评论