代码之家  ›  专栏  ›  技术社区  ›  user113716

在给定特定条件下,手动调用事件处理程序时IE中的错误

  •  15
  • user113716  · 技术社区  · 14 年前

    前言

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

    说明

    当手动调用分配给 onclick ,用投掷 Error: Object doesn't support this action 如果 以下所有条件 符合:

    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
    

    摘要

    同样,我不需要代码解决方案。相反,我很好奇是否有人知道为什么IE是这样实现的。

    非常感谢。


    编辑: 澄清一件事,与实际功能似乎没有任何区别。命名参数,而不是命名它们,返回参数,返回文本值,返回未定义,所有这些都没有效果。

    这可能是因为函数似乎从未真正被调用。正如我在下面的注释中所指出的,导致此调用的代码运行良好,因此也不是解析问题。但是当翻译到这个时候,它会看到:

    变量+赋值运算符+多元素+事件处理程序+调用运算符+参数

    …然后抛出错误。我做的操作似乎没有什么不同。有效地删除其中任何一个,错误就会消失。

    如果我在存储处理程序的变量中间添加一个变量,则从它工作的变量中激发它。

    var temp = elem.onclick;
    result = temp( true );    // works
    

    ……但这并不奇怪,因为它实际上与上面的第四个版本相同。

    3 回复  |  直到 14 年前
        1
  •  3
  •   gblazex    13 年前

    至于“为什么”是这样实现的,外界可能没有答案。一个很好的例子是,前IE开发人员,innerHTML的发明者,面对 problems 使用innerHTML本身。

    问为什么也没必要因为

    1. 你可以解决这个问题(正如你在问题中所说的那样)

    另一件要注意的是你的比喻太具体了。这个问题不限于 assignment expression ,您可以用其他类型的 expressions :

    undefined === elem.onclick( true )
    typeof elem.onclick( true )
    elem.onclick( true ) - 1
    alert(elem.onclick( true ))
    
        2
  •  0
  •   Anthony Corbelli    14 年前

    你试过使用找到的说明吗 here

    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);
    
        3
  •  0
  •   Community Ramakrishna.p    7 年前

    尝试一些函数,它实际上只有一个参数并返回一些内容。看看它是否也会产生错误。它可能与参数和函数默认返回值有关。请试着把结果贴回去。

    如果函数没有被调用,问题可能出在onclick属性的解析上。这可能是因为您实际上并没有调用您定义的函数,但是当您将true作为参数传递时,代码会找到一些其他内置IE对象。无论如何,这种行为超出了任何规范,所以我们可以称之为bug。从我自己的问题中你可以看出。

    IE 8 absolute positioned element outside its parent clipping problem

    IE8 bottom:0 in position:absolute behaves like position:fixed