event = addEvent(
addEvent
ничего не возвращает; вы присваиваете undefined
значение отсутствия возврата глобальной переменной event
(так как вы не сказали var event
в функции). Это вызовет исключение в IE, который использует глобальный event
в качестве специального объекта для передачи деталей события обработчикам, и, следовательно, не позволяет вам назначить что-то еще для него.
if (typeof obj.addEventListener != undefined)
typeof
всегда возвращает строку, которая никогда не будет проверяться равной undefined
unvalue, поэтому IE всегда будет принимать ветвь не-IE и завершится ошибкой. Вы имели в виду if (typeof obj.addEventListener !== 'undefined')
со строкой.
obj.detachEvent("on" + type, obj[type + fn]);
Поскольку вы не написали свойство с именами type
и fn
, слипшимися в функции addEvent
, получить что-либо не удастся.
Как говорит Кресент, похоже, что вы используете функцию Resig removeEvent
в сочетании с другой addEvent
, которая не соответствует. Если вы используете его removeEvent
, вам нужно будет использовать его addEvent
, чтобы пойти с ним.
Однако я бы не стал использовать эти функции в любом случае: они довольно хитры. Я знаю, что это был 2005 год, когда этот непродуманный код выиграл конкурс addEvent в quirksmode, но даже тогда мы должны были знать намного лучше. Проблема в том, что он создает строку из имени события и текстовой сериализации кода функции (type+fn
) и использует ее в качестве ключа для хранения обратного вызова. Этот ключ будет выглядеть примерно так: 'mouseoverfunction changeText() {...code...}'
.
Но полагаться на сериализацию функций - ужасная идея. Формат не стандартизирован ECMAScript («Возвращается зависящее от реализации представление функции.»); Есть много браузерных причуд ; и что не менее важно, две разные функции могут легко возвращать одну и ту же строку для текущих методов сериализации браузеров:
var f1= function() {};
var f2= function() {};
f1
и f2
будут иметь одинаковую сериализацию строк, но это не один и тот же объект. Если вы сделали addEvent
для f1
в IE, а затем еще одно для f2
, второе свойство будет использовать ту же сериализованную строку и перезапишет первое свойство. Затем вызов removeEvent
для f1
извлечет функцию для f2
, попытается detachEvent
и произойдет сбой, потому что это не та же функция. Этот пример может выглядеть надуманным, но на самом деле это очень легко сделать случайно, когда вы используете универсальные замыкания, поскольку современный JavaScript делает все больше и больше в наши дни. По этой причине я бы рекомендовал избегать Resig's addEvent
при любых обстоятельствах .
(пользователи jQuery: не волнуйтесь, при всех своих проблемах jQuery не попадает в ловушку использования этого кода.)
Этот хак предназначен для сохранения значения this
, когда IE вызывает функцию changeText
, для которой attachEvent
не устанавливает this
. Но вы даже не используете значение this
, так что вы могли бы обойтись гораздо более простой версией, такой как original addEvent , которая была создана для замены.
По крайней мере, недостатки в том, что addEvent хорошо известны и обнаруживаются сразу же, когда вы тестируете IE, используя this
, вместо того, чтобы ошибаться только в конкретном случае, когда это влияет на вас, может быть очень запутанным и трудным для отладки.
Опять же, в настоящее время вы не используете даже несколько слушателей для одного и того же события, поэтому вы можете легко уйти со старомодным обработчиком событий DOM Level 0, что-то вроде:
window.onload= function() {
var changed= false;
document.getElementById('contactButton').onmouseover= function() {
if (!changed) {
alert('changing text');
}
changed= true;
};
};