web-dev-qa-db-fra.com

Comment actualiser une variable de sélecteur jQuery stockée et capturée

J'ai couru hier dans un problème avec un jquery-selector que j'ai assigné à une variable et ça me rend fou.

Voici un jsfiddle avec testcase:

  • assigner le .elem à mon obj var
  • connectez les deux longueurs à la console. Résultat => 4
  • Supprimer le n ° 3 du DOM
  • connectez-vous à la console => le n ° 3 supprimé est toujours là et sa longueur est encore de 4 . à la variable et ne peut pas? être mis à jour
  • connectez-vous à la console. yep Résultat => 3 et le n ° 3 est parti
  • Maintenant, je mets à jour .elem avec une nouvelle largeur de 300
  • la journalisation obj & obj.width m'en a donné 300 .. L'instantané a donc été mis à jour? Ce qui est intéressant, c’est que 3 des 4 divs ont la nouvelle largeur, mais que le # 3 supprimé n’a pas ...

Autre test: ajouter un élément li au domtree et enregistrer les obj et .elem. . elem a le nouveau li et obj pas, parce que c'est toujours le vieil instantané 

http://jsfiddle.net/CBDUK/1/

N'y a-t-il aucun moyen de mettre à jour cet obj avec le nouveau contenu? Je ne veux pas créer un nouvel objet, car dans mon application, de nombreuses informations sont enregistrées dans cet objet, je ne veux pas les détruire.

29
Ralk

Oui, c'est un instantané. En outre, la suppression d'un élément de l'arborescence DOM de la page ne va pas, par magie, effacer toutes les références à l'élément.

Vous pouvez l'actualiser comme suit:

var a = $(".elem");

a = $(a.selector);

Mini-plugin:

$.fn.refresh = function() {
    return $(this.selector);
};

var a = $(".elem");

a = a.refresh();

Cette solution simple ne fonctionne pas avec des traversées complexes. Vous allez devoir créer un analyseur syntaxique pour la propriété .selector afin d'actualiser l'instantané pour ceux-ci.

Le format est comme:

$("body").find("div").next(".sibling").prevAll().siblings().selector
//"body div.next(.sibling).prevAll().siblings()"

Mini-plugin en place:

$.fn.refresh = function() {
    var elems = $(this.selector);
    this.splice(0, this.length);
    this.Push.apply( this, elems );
    return this;
};

var a = $(".elem");
a.refresh() //No assignment necessary
57
Esailija

J'ai aussi aimé la solution @Esailija, mais il semble que this.selector a quelques bugs avec filter . J'ai donc modifié à mes besoins, peut-être que ce sera utile

C’est pour jQuery 1.7.2 que l’actualisation n’a pas été testée sur les instantanés filtrés des versions supérieures.

$.fn.refresh = function() { // refresh seletor
    var m = this.selector.match(/\.filter\([.\S+\d?(\,\s2)]*\)/); // catch filter string
    var elems = null;
    if (m != null) { // if no filter, then do the evarage workflow
        var filter = m[0].match(/\([.\S+\d?(\,\s2)]*\)/)[0].replace(/[\(\)']+/g,'');
        this.selector = this.selector.replace(m[0],''); // remove filter from selector
        elems = $(this.selector).filter(filter); // enable filter for it
    } else {
        elems = $(this.selector);
    }
    this.splice(0, this.length);
    this.Push.apply( this, elems );
    return this;
};

Le code n'est pas si beau, mais cela a fonctionné pour mes sélecteurs filtrés.

1
Roman M. Koss

Si vous utilisez remove(), cela ne supprimera qu'une partie du DOM, mais pas tous les enfants ou les objets associés, mais si vous utilisez empty() sur l'élément, le problème a disparu.

PAR EXEMPLE.:

 $('#parent .child).find('#foo').empty();

Peut-être que cela peut être utile à quelqu'un!

0

Jquery .selector est obsolète, il est préférable d’enregistrer une chaîne avec une valeur de sélecteur sur une variable au moment de l’affectation.

function someModule($selector, selectorText) {
   var $moduleSelector = $selector;
   var moduleSelectorText = selectorText;

   var onSelectorRefresh = function() {
      $moduleSelector = $(moduleSelectorText);
   }
}

https://api.jquery.com/selector/

0
Kattie