IE中的事件处理 [英] Event Handling in IE

查看:154
本文介绍了IE中的事件处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的代码,允许我在第一次用户鼠标移到一个元素上,然后删除事件时,做一些事情。



它在W3C事件模型浏览器中播放不错,但在IE6-8中发生错误。我从另一个问题得到代码,并相信它会处理IE。任何人看到我在做错什么?

 < script type =text / javascript> 
函数setMouseEvent(){
//电话:01 8279 400
event = addEvent(document.getElementById('contactButton'),'mouseover',changeText);
}

function changeText(){
alert(working!);
removeEvent(document.getElementById('contactButton'),'mouseover',changeText);
}

函数addEvent(obj,type,fn){
if(typeof obj.addEventListener!= undefined){
obj.addEventListener(type,fn,假);
}
else if(typeof obj.attachEvent!= undefined){
obj.attachEvent(on+ type,fn);
}
}

function removeEvent(obj,type,fn){
if(typeof obj.addEventListener!= undefined){
obj.removeEventListener (type,fn,false);
}
else if(typeof obj.attachEvent!= undefined){
obj.detachEvent(on+ type,obj [type + fn]);
obj [type + fn] = null;
obj [e+ type + fn] = null;
}
}

window.onload = setMouseEvent;
< / script>

更新:我刚刚在最新的Chrome,Opera和FF中测试没有问题,但是当我鼠标悬停时,Safari不会执行任何操作,IE如上所述抛出了错误onload。

解决方案

  event = addEvent(

addEvent 不返回任何东西;您将未定义的缺少返回值分配给全局变量事件(因为你没有在函数中说过 var event ),这将导致IE中出现异常,它使用全局事件作为特殊对象,将事件细节传递给处理程序,因此不允许您为其分配其他内容。

  if(typeof obj.addEventListener!= undefined)

typeof 总是返回一个字符串,这将永远不会测试等于 undefined unvalue,所以IE将永远不会n-IE fork并失败。你的意思是 if(typeof obj.addEventListener!=='undefined'),用一个字符串。

  obj.detachEvent(on+ type,obj [type + fn]); 

由于您尚未写入名称为 fn 粘在一起在 addEvent 函数中,这将无法检索任何内容。 >

正如Crescent所说,看起来您正在使用Resig的 removeEvent 函数,与不同的 addEvent 不匹配。如果你使用他的 removeEvent ,你将需要使用他的 addEvent



但是,我不会使用这些功能:他们很狡猾。我知道这是2005年,当这个不合理的代码赢得quirksmode的addEvent比赛,但即使这样我们应该知道更好。问题是它从事件名称和文本序列化功能代码( type + fn )创建一个字符串,并将其用作存储回调的键。这个键会像'mouseoverfunction changeText(){... code ...}'



但依靠功能序列化是一个可怕的想法。该格式不由ECMAScript标准化(返回函数的实现相关表示);有许多浏览器怪癖;并且至少两个不同的功能可以轻松地为浏览器的当前序列化方法返回相同的字符串:

  var f1 = function() {}; 
var f2 = function(){};

f1 f2 将具有相同的字符串序列化,但它们不是相同的对象。如果您在IE上为 f1 执行 addEvent ,然后另一个 f2 ,第二个属性将使用相同的序列化字符串并覆盖第一个属性。然后调用 removeEvent f1 将检索 f2的功能 ,尝试 detachEvent 它并失败,因为它不是相同的功能。这个例子可能看起来很有挑战性,但是当您使用通用闭包时,实际上非常容易做到这一点,因为现代JavaScript越来越多。因此,我建议在所有情况下,避免使用Resig的 addEvent



jQuery用户:不用担心,jQuery不会陷入使用此代码的陷阱。)



这个黑客是保存 this value,当您的 changeText 函数由IE调用时,其 attachEvent 不设置这个。但是,您甚至不使用这个值,所以你可以使用更简单的版本,例如原始addEvent 被创建为替换。



至少有缺点的 addEvent是众所周知的,当您使用在IE上测试时立即显示,而不是仅在特定情况下出错,当它影响你时,很可能会非常混乱,很难调试。



然后再次,你目前还没有为同一个事件使用多个监听器,所以你可以轻松地使用一个老式的DOM Level 0事件处理程序,如:

  window.onload = function(){ 
var changed = false;
document.getElementById('contactButton')。onmouseover = function(){
if(!changed){
alert('changing text');
}
changed = true;
};
};


I have the code included below that allows me to do something the first time a user mouses over an element and then remove the event.

It plays nice in the W3C event model browsers but keeps throwing an error in IE6-8. I got the code from another question and believed it would handle IE. Anyone see what I'm doing wrong?

    <script type="text/javascript">
    function setMouseEvent() {
        //Tel: 01 8279 400
        event = addEvent(document.getElementById('contactButton'), 'mouseover', changeText);
    }

    function changeText() {
        alert("worked!");
        removeEvent(document.getElementById('contactButton'), 'mouseover', changeText);
    }

    function addEvent(obj, type, fn) {
        if (typeof obj.addEventListener != undefined) {
            obj.addEventListener(type, fn, false);
        }
        else if (typeof obj.attachEvent != undefined) {
            obj.attachEvent("on" + type, fn);
        }
    }

    function removeEvent(obj, type, fn) {
        if (typeof obj.addEventListener != undefined) {
            obj.removeEventListener(type, fn, false);
        }
        else if (typeof obj.attachEvent != undefined) {
            obj.detachEvent("on" + type, obj[type + fn]);
            obj[type + fn] = null;
            obj["e" + type + fn] = null;
        }
    }

    window.onload = setMouseEvent;
</script>

Update: i just tested in the latest Chrome, Opera and FF with no issues but Safari does nothing when I mouse over and IE is throwing the errors onload as mentioned.

解决方案

event = addEvent(

addEvent doesn't return anything; you're assigning the undefined lack-of-return-value to a global variable event (since you've not said var event in the function). This will cause an exception in IE, which uses the global event as a special object to pass event details to handlers, and consequently doesn't allow you to assign something else to it.

if (typeof obj.addEventListener != undefined)

typeof always returns a string, which will never test equal to the undefined unvalue, so IE will always take the non-IE fork and fail. You meant if (typeof obj.addEventListener !== 'undefined'), with a string.

obj.detachEvent("on" + type, obj[type + fn]);

Since you've not written a property with the name of type and fn stuck together in the addEvent function, this will fail to retrieve anything.

As Crescent says, it looks like you're using Resig's removeEvent function, paired with a different addEvent that doesn't match. If you use his removeEvent you will need to use his addEvent to go with it.

However, I wouldn't use these functions anyway: they're pretty dodgy. I know it was 2005 when this ill-conceived code ‘won’ quirksmode's addEvent contest, but even then we should have known a lot better. The problem is it creates a string from the event name and the textual serialisation of the function code (type+fn), and uses it as a key to store a callback. This key will look something like 'mouseoverfunction changeText() {...code...}'.

But relying on function serialisation is a terrible idea. The format is not standardised by ECMAScript ("An implementation-dependent representation of the function is returned."); there are many browser quirks; and not least, two different functions can easily return the same string for browsers' current serialisation methods:

var f1= function() {};
var f2= function() {};

f1 and f2 will have the same string serialisation, but they're not the same object. If you did an addEvent for f1 on IE, and then another one for f2, the second property would use the same serialised string and overwrite the first property. Then calling removeEvent for f1 would retrieve the function for f2, try to detachEvent it and fail because it's not the same function. This example may look contrived, but it's actually extremely easy to do accidentally when you're using generic closures, as modern JavaScript does more and more these days. For this reason I'd recommend avoiding Resig's addEvent in all circumstances.

(jQuery users: don't worry, for all its problems jQuery does not fall into the trap of using this code.)

This hack is there to preserve the this value when your changeText function is called back by IE, whose attachEvent doesn't set this. But you don't even use the this value, so you could have got away with a much simpler version, such as the original addEvent it was created to replace.

At least the shortcomings of that addEvent are well-known and show up immediately when you test on IE using this, instead of only going wrong in a particular case that, when it affects you, is likely to be extremely confusing and hard to debug.

Then again, you aren't currently using even multiple listeners for the same event, so you could easily get away with a old-fashioned DOM Level 0 event handler, something like:

window.onload= function() {
    var changed= false;
    document.getElementById('contactButton').onmouseover= function() {
        if (!changed) {
            alert('changing text');
        }
        changed= true;
    };
};

这篇关于IE中的事件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆