web-dev-qa-db-fra.com

Contrôle de la valeur de «this» dans un événement jQuery

J'ai créé un "contrôle" en utilisant jQuery et utilisé jQuery.extend pour aider à le rendre aussi OO que possible.

Lors de l'initialisation de mon contrôle, je connecte différents événements de clic comme

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

Notez que je passe "ceci" comme argument de données dans la méthode de liaison. Je le fais pour pouvoir accéder aux données attachées à l'instance de contrôle plutôt qu'à partir de l'élément qui déclenche l'événement click.

Cela fonctionne parfaitement, mais je soupçonne qu'il existe une meilleure façon

Après avoir utilisé Prototype dans le passé, je me souviens d'une syntaxe de liaison qui vous permettait de contrôler la valeur de "ceci" dans l'événement.

Quelle est la méthode jQuery?

72

Vous pouvez utiliser jQuery.proxy() avec une fonction anonyme, juste un peu maladroit que 'context' est le deuxième paramètre.

 $("#button").click($.proxy(function () {
     //use original 'this'
 },this));
100
Torbjörn Nomell

J'aime ta façon, en fait d'utiliser une construction similaire:

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

et la première ligne de this.onClick:

var self = event.data.self;

J'aime cette façon parce que vous obtenez à la fois l'élément cliqué (comme ceci) et l'objet "this" en tant que soi sans avoir à utiliser de fermetures.

37
davidfurber

jQuery a le jQuery.proxy méthode (disponible depuis 1.4).

Exemple:

var Foo = {
  name: "foo",

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

$("#test").click($.proxy(Foo.test, Foo))
// "foo" alerted
32
benpickles

Je ne pense pas que jQuery ait une fonctionnalité intégrée pour cela. Mais vous pouvez utiliser une construction d'assistance comme celle-ci:

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));

De cette façon, vous pouvez créer des "fonctions wrapper" dynamiques avec createDelegate () qui appellent la méthode avec un objet donné comme sa portée "this".

Exemple:

function foo() {
    alert(this);
}

var myfoo = foo.createDelegate("foobar");
myfoo(); // calls foo() with this = "foobar"
21
Ferdinand Beyer

Les navigateurs compatibles HTML 5 fournissent un méthode de liaison sur Function.prototype qui est probablement la syntaxe la plus propre et qui ne dépend pas du framework, bien qu'elle ne soit pas intégrée à IE jusqu'à IE 9. (Il y a un - polyfill pour les navigateurs sans, cependant.)

Sur la base de votre exemple, vous pouvez l'utiliser comme ceci:

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

(note latérale: le premier bind de cette instruction fait partie de jQuery et n'a rien à voir avec Function.prototype.bind)

Ou pour utiliser jQuery un peu plus concis et à jour (et éliminer la confusion de deux types différents de binds):

$('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this));
5
JLRishe

vous pouvez utiliser la méthode javascript bind comme ceci:

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

var object = {coolValue: "bla"};


$("#bla").bind('click', coolFunction.bind(object));
4
Orlando

jQuery ne prend pas en charge les liaisons et la méthode préférée consiste à utiliser des fonctions.

Parce qu'en Javascript, this.availableCategoryClick ne signifie pas appeler la fonction availableCategoryClick sur cet objet, jQuery conseille d'utiliser cette syntaxe préférée:

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

Les concepts OO en Javascript sont difficiles à comprendre, la programmation fonctionnelle est souvent plus facile et plus lisible.

2
Vincent Robert

Voyant que les fonctions changent de portée, la façon la plus courante est de le faire à la main, avec quelque chose comme var self = this.

var self = this

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