2010-02-11 2 views
5

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

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.

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

ответ

6

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

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

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

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

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

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

document.body.scrollLeft 

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

var viewport= document.compatMode==='CSS1Compat'? document.documentElement : document.body; 
return {x: ev.clientX+viewport.scrollLeft, y: ev.clientY+viewport.scrollTop}; 
+0

Это отличный старт, спасибо! – Matt

0

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

Например:

addHandler(function(ev) { someObject.onMouseMove(ev); }); 
Смежные вопросы