2009-05-21 6 views
24

Come sostituire un elemento in jQuery e restituire l'elemento di sostituzione anziché l'elemento rimosso?Sostituzione di un elemento e restituzione di quello nuovo in jQuery

Ho il seguente scenario. Ho molte caselle di controllo e una volta che si fa clic su una di esse, tale casella di controllo viene sostituita da un'icona di caricamento. Una volta che alcune cose AJAX si verificano, l'icona di caricamento viene sostituita da un'icona di spunta.

Utilizzando jQuery replaceWith, si farebbe una cosa del genere:

$("input[type='checkbox']").click(function() { 

    $(this).replaceWith("<img src='loading.jpg' alt='loading'/>"); 
    $.post("somepage.php"); 
    $(this).replaceWith("<img src='tick.jpg' alt='done'/>"); 

}); 

Tuttavia, questo non funziona perché replaceWith restituisce l'elemento che è stato rimosso, non quello che è stato aggiunto. Quindi, una volta completato il materiale AJAX, loading.jpg rimarrà lì per sempre.

C'è un modo per restituire l'elemento di sostituzione senza selezionarlo?

Grazie in anticipo.

risposta

22

Dare il caricamento dell'immagine di una classe, poi nel post callback, utilizzare la classe come selettore per trovare l'immagine che hai appena iniettato .

$("input[type='checkbox']").click(function() { 
    $(this).replaceWith("<img src='loading.jpg' alt='loading' class='loading-image' />"); 
    $.post("somepage.php", function() { 
     $('.loading-image').replaceWith("<img src='tick.jpg' alt='done'/>"); 
    }); 
}); 

Se si può avere molti di questi in esecuzione alla volta, è possibile ottenere il genitore più vicino di this e utilizzarlo come contesto per la ricerca per la classe.

EDIT: Un'altra alternativa che utilizza una variabile per memorizzare il nuovo elemento ed elimina la necessità di applicare la classe e la ricerca per il nuovo elemento quando la funzione restituisce.

$("input[type='checkbox']").click(function() { 
    var loading = $("<img src='loading.jpg' alt='loading' />"); 
    $(this).replaceWith(loading); 
    $.post("somepage.php", function() { 
     loading.replaceWith("<img src='tick.jpg' alt='done'/>"); 
    }); 
}); 
+4

Invece di usare una classe .loading-image, non potresti semplicemente mantenere il riferimento al caricamento img e metterlo nella callback, invece cercarlo di nuovo con $ ('. Loading-image')? – cdmckay

+0

La domanda (e la risposta) era specifica per sostituireWith che restituisce l'elemento che è stato rimosso, non l'elemento che è stato creato. È possibile creare l'elemento e memorizzare un riferimento ad esso in una variabile, quindi eseguire la sostituzione. In tal caso, penso di sì, potresti usare il riferimento e non guardarlo di nuovo. – tvanfosson

2

Si potrebbe dare un ID univoco utilizzando l'indice:

$("input[type='checkbox']").click(function() { 
    var index = $("input[type='checkbox']").index(this); 
    $(this).replaceWith("<img src='loading.jpg' id='myLoadingImage" + index + "' alt='loading'/>"); 
    $.post("somepage.php"); 
    $('#myLoadingImage'+index).replaceWith("<img src='tick.jpg' alt='done'/>"); 

}); 
+0

Scusa, avrei dovuto essere più chiaro. Ho molte di queste caselle di controllo, quindi non posso fare affidamento sugli ID. –

+0

Ho aggiornato il codice. Ora ottiene un ID univoco utilizzando l'indice della casella di controllo. –

+0

Anche se più veloce di tvanfosson, è ancora una ricerca dispendiosa, dai un'occhiata alla risposta di Keeper. – cdmckay

13

Creare un elemento e usarlo come parametro per ReplaceWith:?

 

$('input[type=checkbox]').click(function() { 
    var img = document.createElement('img'); 
    img.src = 'loading.jpg'; 
    $(this).replaceWith(img); 
    $.post('somepage.php', function() { 
     $(img).replaceWith('<img src="tick.jpg" alt="done"/>'); 
    }); 
}); 
 
+0

Mi piace questo, senza ingombrare con classi o ID aggiuntivi, sai esattamente quale img sostituire. Molto pulito. –

+1

+1 Non l'ho visto fino a quando non ho aggiornato la mia risposta con codice simile. Userei comunque jQuery per creare il nuovo elemento. – tvanfosson

-1

perché non fare un oggetto jQuery intermedia, come questo ...

$("input[type='checkbox']").click(function() { 
    var insertedElement = $("<img src='loading.jpg' alt='loading'/>"); 
    $(this).replaceWith(insertedElement); 
    $.post("somepage.php"); 
    var anotherInsertedElement = $("<img src='tick.jpg' alt='done'/>"); 
    $(this).replaceWith(anotherInsertedElement); 
    //do something with either of the inserted elements 
}); 
+0

Hai errori di sintassi in questo codice –

+0

Inoltre, il riferimento alla casella di controllo originale $ (this) viene perso una volta che viene chiamato il metodo replaceWith, quindi anche dopo aver corretto gli errori di sintassi, non funziona. –

+0

Inoltre, $ .post è asincrono. – cdmckay

0

Il motivo per il codice non funziona è che il primo replaceWith sostituisce l'articolo che si riferisce a questo. Il secondo replaceWith tenta di sostituirlo di nuovo, ma poiché è già andato, non c'è nulla da sostituire. E l'icona del segno di spunta non verrà mostrata.

La soluzione migliore è utilizzare la funzione di callback post suggerita da tvanfosson.

0

Controllare questo.

$.fn.replaceWithMod = function(obj) { 
var $a = $(obj); 
this.replaceWith($a); 
return $a; 
}; 

var newObj = $('a').replaceWithMod('<div>New Created Object</div>'); 
$(newObj).css('color','green'); 
0

ho scritto un po 'di plugin per ottenere un risultato simile, perché mi piace essere in grado di recuperare un puntatore per il nuovo elemento in una riga di codice.

(function($){ 
    $.fn['overwrite'] = function(target){ 
     $(target).replaceWith(this); 
     return this; 
    } 
}(jQuery)); 

Esempio di utilizzo:

$("input[type='checkbox']").click(function() { 
    var $loading = $("<img src='loading.jpg' alt='loading' class='loading-image' />").overwrite(this); 
    $.post("somepage.php", function() { 
     $loading.replaceWith("<img src='tick.jpg' alt='done'/>"); 
    }); 
}); 
0

Se non c'è una necessità di utilizzare specificamente il metodo ReplaceWith - è possibile utilizzare il metodo replaceAll che è l'opposto di ReplaceWith.

Vedere la risposta qui: (answer to a similar question asked a year later) replaceAll sostituisce ciascun elemento nell'oggetto passato come parametro o gli elementi corrispondenti selettore passato come parametro con gli elementi corrispondenti e restituisce gli elementi corrispondenti (il nuovo contenuto).

In questo modo, la modifica in risposta di tvanfosson (e il codice a risposta di Keeper) sarebbe simile a questa:

$("input[type='checkbox']").click(function() { 
    var loading = $("<img src='loading.jpg' alt='loading' />").replaceAll($(this)); 
    $.post("somepage.php", function() { 
     loading.replaceWith("<img src='tick.jpg' alt='done'/>"); 
    }); 
}); 

E 'solo una linea più breve, ma per brevità e per includere la possibilità di utilizzare replaceAll() Ho ritenuto opportuno aggiungere questa risposta a questa domanda vecchia e più vista.

Problemi correlati