2012-07-22 18 views
5

Supponiamo di avere il seguente requisito: Aggiungere l'elemento e all'elemento con ID "x" se esiste un tale elemento, altrimenti aggiungere e al corpo.C'è un modo elegante per selezionare un elemento in JQuery se un altro non esiste?

In DOM livello 0, posso scrivere:

var parent = document.getElementById("x") || document.body; 
parent.appendChild(e); 

In jQuery, seguente fa non lavoro:

var parent = $("#x") || $("body"); 
parent.append(e); 

perché se nessun elemento con id x esiste, il primo disgiunti restituisce l'oggetto jquery vuoto, con è vero, non falsi, quindi lo append non fa nulla. Io posso , tuttavia, scrivo:

var parent = $("#x")[0] || $("body")[0]; 
parent.appendChild(e); 

ma questa soluzione è un po 'goffo, perché l'indicizzazione l'oggetto jQuery mi torna a HTMLElements, quindi devo usare appendChild invece di append. Mentre questo funziona, mi chiedo se questa combinazione di livelli sia appropriata o indicativa di un cattivo design.

Potrebbe esserci un modo di utilizzare first()? Forse potrei creare un oggetto jQuery che era essenzialmente un array il cui primo elemento era il div con id x, e il secondo era il corpo. So che posso farlo con il modulo costruttore jQuery che accetta un array di elementi, ma poi torno a un mix di livelli. So anche come verificare l'esistenza di un elemento con id x ($("#x").length), ma non riesco a vedere come questo porterà ad un modo elegante per esprimere "l'elemento con id x se esiste, altrimenti il ​​corpo".

Esiste una tale formulazione?

risposta

2

Invece di usare jQuery per selezionare l'elemento, si potrebbe utilizzare per avvolgere il native DOM chiama:

$(document.getElementById("foo") || document.body) 

non è esattamente elegante (o realmente anche usando jQuery), né una tecnica universalmente applicabile, ma si finisce con qualcosa che si può aggiungere alla (e incorrere in una relativamente poco costoso invocazione jQuery solo una volta).

Non sarà possibile utilizzare first() - ad esempio, $("#foo, body").first(); - perché l'ordine in cui restituisce elementi selezionato è basata sull'ordine DOM, non selettore cassa (grazie, @muistooshort)

+0

Ooh, questo è carino, comunque - a meno che jQuery non faccia un po 'di magia veramente seria qui - ha lo svantaggio delle prestazioni di selezionare * tutti * gli elementi prima di restituire il primo anziché il cortocircuito. Tuttavia, se ci preoccupiamo di quel livello di prestazioni, in realtà non dovremmo usare jQuery in primo luogo. – Matchu

+3

No, questo non funzionerà poiché ["L'ordine degli elementi DOM nell'oggetto jQuery restituito potrebbe non essere identico, poiché saranno nell'ordine del documento."] (Http://api.jquery.com/multiple- selettore /), ad esempio: http://jsfiddle.net/ambiguous/edYY6/. Questo ti darà '' ogni volta. –

+0

Concordato che questo è molto bello. Però va bene con uno di ciascuno (o dovrebbe essere), perché il primo ha un id, che dovrebbe essere unico nella pagina, e il secondo è ** l'elemento del corpo **. Dovrebbe esserci solo uno di questi in HTML. –

3

Onestamente, io non davvero che questo è estremamente dettagliato:

var parent = $('#x'); 
if(parent.length == 0) parent = $('body'); 

E il suo intento è anche abbastanza chiaro. Potresti anche avvolgerlo in una funzione se questo idioma viene fuori molto.

Inoltre, ecco una forma ternaria che spara solo ogni query una volta (anche se è un trade-off sulla leggibilità):

var parent = (x = $('#header')).length ? x : $('body'); 
+2

Ti potrebbe usa '$ (" # x "). lunghezza? $ ("# x"): $ ("corpo") '. –

+0

Grazie per la rapida risposta. Mi sento male a chiedere un one-liner (troppo comune su SO, lo so !!) ma sono rimasto sorpreso dal fatto che DOM Level 0 avesse una formulazione concisa, quindi probabilmente jquery dovrebbe. :) –

+0

@RayToal: aggiunto un one-liner ben funzionante, sebbene sia nettamente meno leggibile.Continuerò comunque a votare facendo una riga avvolgendo la versione a due righe in una funzione, specialmente se ne esce molto ... ma se è usata solo una volta, allora meh. – Matchu

Problemi correlati