2012-08-08 26 views
28

Ho eseguito ieri un problema con un jquery-selector assegnato a una variabile e mi sta facendo impazzire.Come aggiornare una variabile selettrice jquery memorizzata e istantanea

Ecco un jsfiddle con TestCase:

  • assegnare il .elem al mio obj var
  • registro entrambe le lunghezze alla console. Risultato => 4
  • Rimuovere # 3 dal DOM
  • registro obj alla console => il rimosso 3 # è ancora lì e la lunghezza è ancora 4. ho capito quella query jQuery è snapshotted? alla variabile e non può? no? essere aggiornati
  • registro .elem alla console .. sì Risultato => 3 e la # 3 è andato
  • Ora aggiorno .elem con una nuova larghezza di 300
  • registrazione obj & obj.width mi dà 300 .. Quindi l'istantanea è stata aggiornata? La cosa interessante è che 3 dei 4 div hanno la nuova larghezza, ma il rimosso 3 # non lo fa ...

Un altro test: Aggiunta di un elemento li al domtree e la registrazione obj e .elem. .elem ha il nuovo Li e obj non lo fa, perché è ancora il vecchio snapshot

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

Non c'è un modo per aggiornare questo obj con i nuovi contenuti? Non voglio creare un nuovo oggetto, perché nella mia applicazione ci sono molte informazioni salvate in quell'oggetto, non voglio distruggere ...

risposta

56

Sì, è un'istantanea. Inoltre, la rimozione di un elemento dalla struttura DOM della pagina non sta per scomparire magicamente da tutti i riferimenti all'elemento.

È possibile aggiornare in questo modo:

var a = $(".elem"); 

a = $(a.selector); 

Mini-plugin:

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

var a = $(".elem"); 

a = a.refresh(); 

Questa semplice soluzione non funziona con attraversamenti complessi però. Dovrai preparare un parser per la proprietà .selector per aggiornare l'istantanea per quelli.

Il formato è simile:

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

In-luogo mini-plug:

$.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 
+0

Grazie per l'aiuto e la spiegazione! Ha funzionato molto bene con la chiamata .selector. È un metodo interno jquery? non è stato possibile trovare alcuna documentazione per quella chiamata. Comunque .. Ho cambiato un po 'il mio codice e ho creato un nuovo setter per quel conteggio e lo ho chiamato con setCount ($ ... length) che funziona anche abbastanza bene. – Ralk

+0

@Ralk la proprietà '.selector' è tecnicamente interna sì. – Esailija

+1

@Esailija - Non funziona qui: http://jsfiddle.net/nJeqf/ (La proprietà .selector era deprecata in jQuery 1.7). http://api.jquery.com/selector/ –

1

Mi è piaciuto anche la soluzione @Esailija, ma sembra che this.selector ha alcuni bug con filtro. Così ho modificato per le mie esigenze, forse sarà utile a qualcuno

Questo è stato per jQuery 1.7.2 didn `t di aggiornamento di prova su istantanee filtrate sulle versioni superiori

$.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; 
}; 

codice è non così bello, ma ha funzionato per i miei selettori filtrati.

0

Jquery .selector è obsoleto, è meglio per ricordare stringa con valore del selettore a qualche variabile nel momento in cui si assegna

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

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

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

0

Se si utilizza remove() rimuoverà solo una parte il DOM ma non tutti i bambini o relativi, invece se si utilizza empty() sull'elemento il problema è andato.

es .:

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

forse può essere utile a qualcuno!

Problemi correlati