Как передать контекст this в обработчик событий? - PullRequest
49 голосов
/ 30 марта 2011

Я знаю, что этот вопрос не имеет особого смысла, но позвольте мне попытаться немного уточнить.

У меня есть класс, называемый 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 .Некоторые могут ожидать, что this внутри обработчика событий ссылается на экземпляр ScrollBanner , но, к сожалению, это не так.Он относится к элементу, который инициировал событие click, в данном случае span # banner1-nav

Каков наилучший способ получить this для ссылки на ScrollBanner экземпляр класса?

Ответы [ 2 ]

86 голосов
/ 30 марта 2011

Старый / традиционный способ:

Захват 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));
1 голос
/ 21 октября 2014

Я знаю, что это старый вопрос, но я видел, что в комментариях упоминается $ .proxy (). Да, это меняет контекст объекта, но не в событии jQuery.

 $('.selector').click( $.proxy( function() {
     console.log(this); /* this is set to .selector */
 }, this));

$. Proxy () возвращает функцию в области, на которую ссылался this, но затем эта функция возвращается и используется click(), которая затем изменяет область на элемент .selector.

Я проверял это минуту назад, но если я ошибся, пожалуйста, скажите

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...