Управление значением 'this' в событии jQuery - PullRequest
72 голосов
/ 06 февраля 2009

Я создал «элемент управления» с помощью jQuery и использовал jQuery.extend, чтобы сделать его как можно более удобным.

Во время инициализации моего элемента управления я подключаю различные события щелчка, как, например,

jQuery('#available input', 
            this.controlDiv).bind('click', this, this.availableCategoryClick);

Обратите внимание, что я вставляю 'this' в качестве аргумента данных в методе bind. Я делаю это так, чтобы получить данные, прикрепленные к экземпляру элемента управления, а не из элемента, который запускает событие click.

Это прекрасно работает, однако я подозреваю, что есть лучший способ

Используя Prototype в прошлом, я помню синтаксис привязки, который позволял вам контролировать значение «this» в событии.

Что такое способ jQuery?

Ответы [ 8 ]

100 голосов
/ 20 апреля 2011

Вы можете использовать jQuery.proxy() с анонимной функцией, просто немного неловко, когда «context» является вторым параметром.

 $("#button").click($.proxy(function () {
     //use original 'this'
 },this));
37 голосов
/ 31 декабря 2009

Мне нравится ваш способ, на самом деле используйте аналогичную конструкцию:

$('#available_input').bind('click', {self:this}, this.onClick);

и первая строка this.onClick:

var self = event.data.self;

Мне нравится этот способ, потому что тогда вы получаете как элемент, по которому щелкнули (как этот), так и объект "this", как себя, без необходимости использовать замыкания.

32 голосов
/ 14 февраля 2011

jQuery имеет метод jQuery.proxy (доступно с версии 1.4).

Пример:

var Foo = {
  name: "foo",

  test: function() {
    alert(this.name)
  }
}

$("#test").click($.proxy(Foo.test, Foo))
// "foo" alerted
21 голосов
/ 06 февраля 2009

Я не думаю, что jQuery имеет встроенную функцию для этого. Но вы можете использовать вспомогательную конструкцию, подобную следующей:

Function.prototype.createDelegate = function(scope) {
    var fn = this;
    return function() {
        // Forward to the original function using 'scope' as 'this'.
        return fn.apply(scope, arguments);
    }
}

// Then:
$(...).bind(..., obj.method.createDelegate(obj));

Таким образом, вы можете создавать динамические «функции-оболочки» с помощью метода createDelegate (), который вызывает метод с заданным объектом в качестве области видимости «this».

Пример:

function foo() {
    alert(this);
}

var myfoo = foo.createDelegate("foobar");
myfoo(); // calls foo() with this = "foobar"
5 голосов
/ 24 апреля 2014

HTML 5-совместимые браузеры предоставляют метод связывания на Function.prototype, который, вероятно, является самым чистым синтаксисом и не зависит от фреймворка, хотя он не встроен в IE до IE 9. polyfill для браузеров без него.)

Исходя из вашего примера, вы можете использовать его так:

jQuery('#available input', 
        this.controlDiv).bind('click', this.availableCategoryClick.bind(this));

(примечание: первый bind в этом выражении является частью jQuery и не имеет ничего общего с Function.prototype.bind)

Или использовать немного более лаконичный и современный jQuery (и устранить путаницу между двумя различными типами bind с):

$('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this));
4 голосов
/ 08 марта 2013

Вы можете использовать метод javascript bind следующим образом:

var coolFunction = function(){
  // here whatever involving this
     alert(this.coolValue);
}

var object = {coolValue: "bla"};


$("#bla").bind('click', coolFunction.bind(object));
2 голосов
/ 06 февраля 2009

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

Поскольку в Javascript this.availableCategoryClick не означает вызов функции availableCategoryClick для этого объекта, jQuery советует использовать этот предпочтительный синтаксис:

var self = this;
jQuery('#available input', self.controlDiv).bind('click', function(event)
{
   self.availableCategoryClick(event);
});

Понятия ОО в Javascript трудны для понимания, функциональное программирование часто проще и более читабельно.

1 голос
/ 06 февраля 2009

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

var self = this

$('.some_selector').each(function(){
  // refer to 'self' here
}
...