У меня есть следующая проблема в обработчиках событий в 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 Maps GEvent.bind () С ним, можно передать объект с функцией, Вы хотите стрелять в указанное событие. Я по существу ищу то же самое.
Сегодня многие люди делают это с явным закрытием:
var myobject= new MyObject();
element.onmousemove= function() {
myobject.onMouseMove();
};
Но в будущем вы будете делать это с помощью метода ECMAScript Fifth Edition function.bind
:
element.onmousemove= myobject.onMouseMove.bind(myobject);
(Любые дальнейшие аргументы переданные в function.bind
добавляются к списку аргументов целевой функции при вызове.)
Пока все браузеры не поддерживают function.bind
изначально, вы можете взломать поддержку самостоятельно, используя прототипы и закрытия. См. Нижнюю часть этого ответа для примера реализации.
document.body.scrollLeft
Это только document.body
, если вы находитесь в режиме совместимости IE. Вы же не хотите находиться в режиме причуд. В стандартном режиме doctype это document.documentElement
. Поэтому, если вам нужно поддерживать разные страницы, которые могут использовать любой из режимов, или вам по-прежнему нужно поддерживать IE5 по какой-то причине (будем надеяться, что нет):
var viewport= document.compatMode==='CSS1Compat'? document.documentElement : document.body;
return {x: ev.clientX+viewport.scrollLeft, y: ev.clientY+viewport.scrollTop};
Вам необходимо передать функция-оболочка, которая вызывает ваш обработчик в правильном контексте.
Например:
addHandler(function(ev) { someObject.onMouseMove(ev); });