Как передать этот контекст в обработчик событий?
Я знаю, что этот вопрос не имеет большого смысла, но позвольте мне попытаться немного разъяснить.
У меня есть класс, называемый ScrollBanner, и он выглядит несколько следующим образом (много опущено для краткости):
function ScrollBanner() {
this.initialize = function(selector) {
$('span#banner1-nav').click(this._onClickNavigation);
}
this._onClickNavigation = function(event) {
this.restartTimer(); // this == span#banner1-nav element from this.initialize
//...
}
this.restartTimer() {
//...
}
}
Как вы видите, this.initialize устанавливает обработчик кликов в this._onClickNavigation. Некоторые могут ожидать, что этот внутри обработчика событий ссылается на экземпляр ScrollBanner, но, к сожалению, этого не происходит. Это относится к элементу, который trigerred событие click, в этом случае span # banner1-nav
Каким будет лучший способ получить этот для ссылки на экземпляр класса ScrollBanner?
Ответы
Ответ 1
Старый/традиционный способ:
Захват this
в переменной:
this.initialize = function(selector) {
var that = this;
$('span#banner1-nav').click(function(event) {
that._onClickNavigation(event);
});
}
Вы также можете назначить this
переменной, например. instance
:
function ScrollBanner() {
var instance = this;
// ...
}
и instance
вместо this
во всех вызовах.
Общая идея состоит в том, чтобы хранить this
в переменной в более высокой области.
Способ ECMAScript5:
ECMAScript5 вводит новое свойство функций: .bind()
. Документация MDC показывает реализацию для браузеров, которые ее не поддерживают. С его помощью вы можете привязать определенный контекст к функции:
this.initialize = function(selector) {
$('span#banner1-nav').click(this._onClickNavigation.bind(this));
}
но за кулисами он делает то же самое. Преимущество заключается в том, что вы используете встроенные функции в браузере, который поддерживает.
Обратите внимание, что это отличается от apply
или call
. Оба из них задают контекст и выполнение функции, тогда как bind
устанавливает контекст без выполнения функции.
Способ jQuery:
jQuery предоставляет метод $.proxy()
, который делает то же самое:
$('span#banner1-nav').click($.proxy(this._onClickNavigation, this));
Ответ 2
Я знаю, что это старый вопрос, но я видел, что в комментариях упоминается $.proxy(). Да, он меняет контекст объекта, но не в событии jQuery.
$('.selector').click( $.proxy( function() {
console.log(this); /* this is set to .selector */
}, this));
$. proxy() возвращает функцию в области, которую реферирует this
, но затем эта функция возвращается и используется click()
, которая затем меняет область действия на элемент .selector
.
Я тестировал его минуту назад, но если я понял, что не так, скажите