在给定某些条件下手动调用事件处理程序时IE中出错

use*_*716 15 javascript internet-explorer event-handling

前言

  • 请注意,我不是在寻找代码解决方案,而是要深入了解为什么会出现这种情况.
  • 错误发生在IE(测试7和8),但不是Firefox,Chrome,Safari.

描述

当手动调用分配给的函数时onclick,Error: Object doesn't support this action如果满足以下所有条件,则抛出a :

  1. 您可以通过元素的on[event]属性直接调用该方法.
  2. 你不使用.call().apply().
  3. 你传递一个参数(任何参数,甚至undefined).
  4. 您尝试将返回值分配给变量.

违反任何一条规则,呼叫成功.

该功能本身似乎与它无关.空函数给出相同的结果.

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
Run Code Online (Sandbox Code Playgroud)

摘要

同样,我不需要代码解决方案.相反,我很好奇是否有人深入了解为什么IE以这种方式实现.

非常感谢.


编辑:澄清一件事,实际功能似乎没有任何区别.命名参数,不命名它们,返回参数,返回文字值,返回undefined,所有这些都没有效果.

这很可能是因为函数似乎从未被实际调用过.正如我在下面的评论中指出的那样,导致此调用的代码运行正常,因此它也不是解析问题.但是当解释器到达这个时,它会看到:

Variable + AssignmentOperator + DOMElement + EventHandler + CallOperator + Argument

...并抛出错误.我做的任何操作似乎没有任何区别.有效删除其中任何一个,并且错误消失.

如果我在它的中间添加一个变量来存储处理程序,那么从它工作的变量中激活它.

var temp = elem.onclick;
result = temp( true );    // works
Run Code Online (Sandbox Code Playgroud)

......但这不应该是一个惊喜,因为它实际上与上面的第四个版本相同.

gbl*_*zex 3

至于“为什么”要这样实施,外界恐怕没有答案。一个很好的例子是,当前 IE 开发人员(innerHTML 的发明者)面临innerHTML 本身的问题时。

问为什么也是不必要的,因为

  1. 您不经常显式调用带有参数的事件处理程序
  2. 您可以解决该问题(正如您在问题中所述)

另一件需要注意的是,你的类比太具体了。该问题不仅限于assignment expression,您可以使用其他类型的 重现该问题expressions

undefined === elem.onclick( true )
typeof elem.onclick( true )
elem.onclick( true ) - 1
alert(elem.onclick( true ))
Run Code Online (Sandbox Code Playgroud)