web-dev-qa-db-fra.com

Stocker le sélecteur jquery dans une variable

Dans l'exemple suivant, le stored jQuery selector renvoie la valeur incorrecte . Il est possible de stocker les sélecteurs et pas le résultat?

Le code js:

// storing the jQuery selectors
var
  $container = $( '.container' ),
  $element1  = $container.find( '.element' ),
  $element2  = $( '.element', $container ),
  $element3  = $( '.element' );

// append elements to the container
for( i=0; i<10; ++i ){
  $container.append( $(element_html) );  
}

// try the stored selectors -> returns 0
console.log( "1: " + $element1.length );
console.log( "2: " + $element2.length );
console.log( "3: " + $element3.length );

Pourquoi, si j’utilise les sélecteurs de conteneur pour trouver les éléments, cela fonctionne? C’est parce que le sélecteur renvoie la pointer aux éléments correspondants et non aux éléments?

// this works
console.log( "1: " + $container.find( '.element' ).length );
console.log( "2: " + $( '.element', $container )  .length );
console.log( "3: " + $( '.element' )              .length );

jsFiddle démonstration

30
TheGr8_Nik

Vous avez un malentendu fondamental sur ce que

variableName = $("selector here");

est-ce que. Il ne "stocke pas le sélecteur". Il exécute le sélecteur que vous donnez avec les éléments current du DOM, crée un objet jQuery, place les éléments correspondants dans l'objet jQuery et vous donne une référence à cet objet jQuery. Le sélecteur n'est pas stocké (Modulo JQuery Internals).

Donc, étant donné:

<body>
<div class="foo">x</div>
</body>

Ensuite:

var $divs = $("div.foo");
console.log($divs.length);        // 1

Nous donne ceci:

$divs jQuery object pointing at one div in the DOM

Si nous ajoutons ensuite une autre variable div correspondante:

$('<div class="foo"></div>').appendTo(document.body);

Notre $divs ne pointe toujours que sur le premier; l'ajout d'un autre élément correspondant au DOM n'a aucun effet sur l'objet jQuery référencé depuis $divs.

$divs jQuery object pointing to one div, but there are two in the DOM

Si nous réexécutons la requête à ce stade:

$divs = $("div.foo");

...ensuite nous avons:

$divs jQuery object pointing at both divs in the DOM

Si vous avez un objet jQuery contenant un élément DOM et que vous ajoutez des éléments descendant à cet élément DOM, utilisez cet objet jQuery avec (par exemple) .find pour afficher les descendants. En effet, l'élément DOM parent est déjà présent dans l'objet jQuery. Par exemple, ajouter une span à l'une des divs que nous déjà faisons référence à notre objet jQuery:

$divs jQuery object pointing at both divs in the DOM, one has a span now

Si nous utilisions .find sur $divs à ce moment-là pour rechercher une span, nous le trouverions, car il s'agit d'un descendant de l'un des éléments auxquels nous avons déjà fait référence.

Si vous souhaitez relancer la recherche DOM ultérieurement pour rechercher des éléments correspondants, il vous suffit d'utiliser à nouveau $(); c'est implicite dans ce qui précède, mais pour plus de clarté:

var $divs = $("div.foo");
console.log($divs.length);        // 1
$('<div class="foo"></div>').appendTo(document.body);
console.log($divs.length);        // Still 1
$divs = $("div.foo");
console.log($divs.length);        // Now it's 2

Donc, "stocker un sélecteur", le cas échéant, consiste à stocker la chaîne de sélecteur quelque part, pas l'objet jQuery.

100
T.J. Crowder

Je pense que la réponse acceptée est excellente, mais elle pourrait être interprétée comme suggérant qu’affecter des objets JQuery à des variables est toujours dangereux. Cela est correct - tant que l'objet DOM que la référence de la variable référence n'est pas modifié avant d'y accéder d'une manière qui affecte le code ultérieur.

HTML

<div id="banner-message">
    <p>Hello World</p>
    <button>Change view</button>
</div>

JavaScript

// find elements
var banner = $("#banner-message")
var button = $("button")

// handle click and add class
button.on("click", function(){
  banner.addClass("alt");
  banner.hide().html("New HTML").fadeIn(2000);
})

JsFiddle

1
Bob Ray