Кроссбраузерная обработка событий

Мне нужна кросс-браузерная функция для регистрации обработчиков событий и (в основном) согласованный опыт работы с обработчиками. Мне не нужен полный вес или функциональность такой библиотеки, как jQuery, поэтому я написал свою собственную. Я считаю, что достиг своих целей с помощью приведенного ниже кода, и до сих пор мое тестирование было успешным, но я слишком долго смотрел на него. Есть ли недостатки в моей логике или ошибки, которые я упускаю?

РЕДАКТИРОВАТЬ 1: каждый блок прокомментирован с намерением браузера для ясности. Обновлен блок IE, чтобы не вызывать func сразу (благодаря зоркому глазу Энди Э.).

EDIT 2: Обновлен блок IE для вызова func.call() с this вместо elem.

РЕДАКТИРОВАНИЕ 3: Обновлено для передачи JSLint с "Хорошими частями".

function hookEvent(elem, evt, func)
{
    if (typeof elem === "string")
    {
        elem = document.getElementById(elem);
    }
    if (!elem)
    {
        return null;
    }
    var old, r;
    if (elem.addEventListener)  //w3c
    {
        elem.addEventListener(evt, func, false);
        r = true;
    }
    else if (elem.attachEvent)  //ie
    {
        elem[evt + func] = function ()
        {
            func.call(this, window.event);
        };
        r = elem.attachEvent("on" + evt, elem[evt + func]);
    }
    else                        //old
    {
        old = elem["on" + evt] ? elem["on" + evt] : function (e) { };
        elem["on" + evt] = function (e)
        {
            if (!e)
            {
                e = window.event;
            }
            old.call(this, e);
            func.call(this, e);
        };
        r = true;
    }
    return r;
}

person Billy Jo    schedule 25.08.2010    source источник
comment
jQuery — очень легкая библиотека. Что плохого в его использовании? Кто-то уже сделал всю работу за вас. Или вам просто неинтересно учиться?   -  person Matt Ball    schedule 25.08.2010
comment
@Медведи тебя съедят - 66К плюс, по сравнению с этим, далеко не легкий вес. Особенно, если это все, что ему нужно. @Bill Ayakatubby - Под кросс-браузером вы действительно имеете в виду стандартные вещи, которые IE не обрабатывает должным образом.   -  person Rob    schedule 25.08.2010
comment
@Bears: На данный момент единственная проблема, связанная с кроссбраузерностью, — это регистрация событий, поэтому мне не нужна jQuery или другая библиотека. Если моя ситуация изменится, я пересмотрю необходимость библиотеки.   -  person Billy Jo    schedule 25.08.2010
comment
В последней ветке сейчас действительно мало смысла. Не осталось основных браузеров, которые не поддерживают ни addEventListener, ни attachEvent.   -  person Tim Down    schedule 26.08.2010
comment
перейти на codereview.stackexchange.com   -  person Knu    schedule 30.05.2011


Ответы (1)


В этой строке есть проблема:

r = elem.attachEvent("on" + evt, func.call(elem, window.event));

Это немедленно выполнит func(), вместо того, чтобы прикреплять его в качестве обработчика события. Вместо этого возвращаемое значение func() будет присвоено событию, которое вызовет ошибку, если его тип не "function".

Я понимаю, что вы не хотите использовать фреймворк, но многие (многие) написали фрагменты кроссбраузерной обработки событий. У John Resig есть одна версия, у Google есть "javascript addEvent" и многие другие.

http://www.google.com/search?q=javascript+addevent

person Andy E    schedule 25.08.2010
comment
Спасибо за отзыв, Энди. Я обновил свой код, чтобы отразить вашу находку. - person Billy Jo; 25.08.2010