Глобальный контекст объекта Javascript для обработки событий - PullRequest
5 голосов
/ 11 февраля 2010

У меня есть следующая проблема в обработчиках событий в Javascript. У меня есть объект, у которого есть обработчик события mousemove, например:

function MyObject(){ }
function MyObject.prototype = {

    currentMousePosition: null,
    onMouseMove: function(ev){
       this.currentMousePosition = this.getCoordinates(ev);
    },
    getCoordinates: function(ev){
        if (ev.pageX || ev.pageY)
            return { x: ev.pageX, y: ev.pageY };

        return { x: ev.clientX + document.body.scrollLeft - document.body.clientLeft, y: ev.clientY + document.body.scrollTop - document.body.clientTop };
    }

};

Проблема, которую я пытаюсь решить, решается вокруг контекста объекта. В моей функции onMouseMove он назначает свойство currentMousePosition. Естественно, это не сработает, потому что это статическая функция, обрабатывающая событие mousemove.

Я ищу технику / метод для передачи контекста объекта с помощью моего обработчика событий. Лучший пример, который я могу вспомнить, это функция API Карт Google GEvent.bind () С его помощью вы можете передать объект с функцией, которую вы хотите запустить по указанному событию. По сути, я ищу то же самое.

Ответы [ 2 ]

6 голосов
/ 11 февраля 2010

Сегодня многие люди делают это с явным закрытием:

var myobject= new MyObject();
element.onmousemove= function() {
    myobject.onMouseMove();
};

Но в будущем вы сделаете это с помощью метода пятого издания ECMAScript function.bind:

element.onmousemove= myobject.onMouseMove.bind(myobject);

(Все дополнительные аргументы, переданные function.bind, добавляются к списку аргументов целевой функции при вызове.)

Пока все браузеры не поддерживают function.bind изначально, вы можете взломать поддержку в себе, используя прототипы и замыкания. См. этот ответ для примера реализации.

document.body.scrollLeft

Это только document.body, если вы находитесь в режиме IE Quirks. Вы не хотите быть в Причудливом Режиме. С типом документа Standards Mode вместо document.documentElement. Поэтому, если вам нужно поддерживать разные страницы, которые могут использовать любой из этих режимов, или вам по-прежнему нужна поддержка IE5 (будем надеяться, что нет):

var viewport= document.compatMode==='CSS1Compat'? document.documentElement : document.body;
return {x: ev.clientX+viewport.scrollLeft, y: ev.clientY+viewport.scrollTop};
0 голосов
/ 11 февраля 2010

Вам нужно передать функцию-оболочку, которая вызывает ваш обработчик в правильном контексте.

Например:

addHandler(function(ev) { someObject.onMouseMove(ev); });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...