2012-08-08 8 views
28

Ayer ejecuté un problema con un jquery-selector que asigné a una variable y me está volviendo loco.¿Cómo puedo actualizar una variable de selector de jquery almacenada e insertada

Aquí es un caso de prueba con jsFiddle:

  • asignar el .ELEM a mi obj var
  • registro de ambos extremos a la consola. Resultado => 4
  • Quitar # 3 del DOM
  • registro obj a la consola => se eliminó el # 3 es todavía allí y la longitud es todavía 4. me di cuenta de que la consulta jQuery es snapshotted? a la variable y no puede? ¿no? actualizarse
  • .ELEM registro a la consola .. sip resultado => 3 y el # 3 se ha ido
  • Ahora puedo actualizar .ELEM con un nuevo ancho de 300
  • tala obj & obj.width me da 300 ¿Entonces la instantánea se ha actualizado? Lo interesante es que 3 de los 4 div tienen el nuevo ancho, pero el # 3 eliminado no ...

Otra prueba: Agregar un elemento li al domtree y registrar obj y .elem. .ELEM tiene el nuevo Li y obj no lo hace, porque sigue siendo la vieja foto

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

¿No hay manera de actualizar este obj con el nuevo contenido? No quiero hacer un obj nuevo, porque en mi aplicación hay mucha información guardada en ese objeto, no quiero destruir ...

Respuesta

56

Sí, es una instantánea. Además, eliminar un elemento del árbol DOM de la página no va mágicamente a desaparecer de todas las referencias al elemento.

se puede refrescar que de este modo:

var a = $(".elem"); 

a = $(a.selector); 

Mini-plugin:

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

var a = $(".elem"); 

a = a.refresh(); 

Esta sencilla solución no funciona con recorridos complejos sin embargo. Deberá crear un analizador para la propiedad .selector para actualizar la instantánea.

El formato es como:

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

En lugar de mini-plugin:

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

¡Gracias por tu ayuda y explicación! Funcionó muy bien con la llamada .selector. Es un método interno jquery? no pude encontrar ninguna documentación para esa llamada. De todos modos ... Cambié un poco mi código e hice un nuevo setter para ese conteo y lo llamé con setCount ($ ... length) que también funciona bastante bien. – Ralk

+0

@Ralk la propiedad '.selector' es técnicamente interna, sí. – Esailija

+1

@Esailija - No funciona aquí: http://jsfiddle.net/nJeqf/ (La propiedad .selector estaba en desuso en jQuery 1.7). http://api.jquery.com/selector/ –

1

También me ha gustado solución @Esailija, pero parece que this.selector tiene algunos errores con filtro. Así que modificar para mis necesidades, tal vez sea útil a alguien

Esto fue para jQuery 1.7.2 actualización de prueba en dejase`t instantáneas filtradas en las versiones más altas

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

Código es no tan hermoso, pero funcionó para mis selectores filtrados.

0

Jquery .Selector está en desuso, es mejor remeber cadena con valor de selector de alguna variable en el momento cuando se asigna

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

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

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

0

Si utiliza remove() se eliminará sólo una parte de el DOM pero no todos los hijos o relacionados; en cambio, si usa empty() en el elemento, el problema desaparece.

ej .:

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

tal vez puede ser útil a alguien!