IE中的window.event!== window.event

时间:2012-09-18 01:57:11

标签: javascript internet-explorer

代码:

<html>
<head>
<script type="text/javascript">
  onload = function(){
    document.getElementById('btn1').onclick = function(){   
      if (window === window)  
        alert('window === window')
      else
        alert('window !== window');

      if (window.event === window.event)  
        alert('window.event === window.event')
      else
        alert('window.event !== window.event' );   
    }
  }
</script>
</head>
<body>
<button id="btn1" >click</button>
</body>
</html>

结果:

IE(我已经测试过IE6 - IE8)说:

window === window
window.event !== window.event

所有其他浏览器都说:

window === window
window.event === window.event

IE的回应是什么原因?感谢。

3 个答案:

答案 0 :(得分:7)

我做了一些实验。看起来每次在IE中访问window.event时,都会得到一个新对象:

document.body.onclick = function() {
    var u = window.event, v = window.event;
    console.log(window.event == window.event); // false
    console.log(u == v); // false
    console.log(u == u); // true
    console.log(v == v); // true
    console.log(u == window.event); // false
    console.log(v == window.event); // false
};

因此,每当您检索window.event时,IE都会创建一个新对象。如果您针对自身(u == uv == v)测试该对象,则为true。如果你针对另一个window.event对象进行测试,那就是假的。

(请注意,这与NaN的行为不同,因为var a = NaN; console.log(a == a);false。)

window.event视为生成器,更像是IE中的window.createCopyOfLastEvent()window.event是一个始终返回新对象的getter。以下说明了这一点:

document.body.onclick = function() {
    var v = window.event;
    v.a = 1;
    console.log(v.a); // 1
    console.log(window.event.a); // undefined
};

在上面的示例中,window.event.a在记录时为undefined,因为它引用的是与a = 1不同的对象。

为了进一步说明,可以在纯JavaScript中重新创建此行为(在ES5支持的浏览器中:IE9,或FF,Chrome或Safari的最新版本):

var weirdObject = Object.create({ }, {
    whoa: {
        get: function() {
            return new Object();
        }
    }
});

console.log(weirdObject.whoa == weirdObject.whoa); // false

或许甚至可能更陌生:

Object.defineProperty(window, 'ahh', {
    get: function() {
        return Math.random();
    }
});

console.log(ahh == ahh); // false

答案 1 :(得分:3)

更新: 阅读:IE Bug (window === top) === false

简而言之 - IE被破坏,并且不能很好地比较主机对象。

并非所有浏览器都支持window.event。大多数使用传递给函数的event对象。 (window.event被视为IE特定内容,但Chrome似乎已将其复制。)

试试这个:

 document.getElementById('btn1').onclick = function(event){   
  if (!event) {event = window.event;}

  alert([typeof event, typeof window.event])

  if (window === window)  
    alert('window === window')
  else
    alert('window !== window');

  if (window.event === window.event)  
    alert('window.event === window.event')
  else
    alert('window.event !== window.event' );   
}

}

答案 2 :(得分:3)

比较行为是ECMAScript-compliant当代码在不支持window.event的浏览器中执行时,我们会有效地比较返回true的两个未定义值。在MSIE上window.event只是一个MSEventObj接口,这意味着对它的两个不同的调用将返回相同的对象,并且它们将进行错误的比较。

这意味着,window.event永远不会相同,因此比较毫无意义。如果您正在尝试比较事件类型,可以通过强制进行字符串比较来进行鸭子类型比较:

//false, you're either comparing undefined values or different objects
console.log(window.event == window.event);

//true, you're either comparing two "undefined" or "[object MSEventObj]" strings
console.log((""+window.event) === (""+window.event));

我不知道您需要执行此特定检查的实际情况。确定事件类型应通过检查其type属性:

来完成
function doSomething(e) {
  if (!e) var e = window.event;
  alert(e.type);//or whatever
}

请注意,这应该从作为DOM一部分的脚本执行 - 而不是从开发人员工具的控制台执行:

don't

Overview of cross-browser event properties' quirks