2011-07-28 12 views
46

C'è un modo elegante per trasformare [$(div), $(span), $(li)] in $(div, span, li)?Trasforma array di elementi jQuery in jQuery wrapping set di elementi

Quello che mi serve è un insieme di elementi jQuery invece di una serie di elementi jQuery. Mi piacerebbe farlo in poche righe di codice il più possibile e con un minimo (se necessario) looping.

Edit: Per quelli di voi confusi da questa domanda, questo codice viene copiato e incollato da Firebug utilizzando console.log su una serie di elementi che sono già selezionati.

+3

jQuery deve chiamare gli elementi tra virgolette: '$ (" li ")' – jackJoe

+2

@jackJoe Penso che stia citando firebug direttamente. – fncomp

+0

Vuoi davvero dire che vuoi girare questo: '[$ (a), $ (b), $ (c)]' nel risultato di questo: '$ (a, b, c)'? Il fatto che tutti i parametri siano 'li' sta rendendo questo abbastanza confuso. – jfriend00

risposta

46

jQuery's map() function è perfetto per rimodellare gli array e/o le raccolte di jQuery.

Quindi, dato un allineamento impostato in questo modo:

var arrayOfJQ_Objects = [$("div"), $("span"), $("li")]; 


Questa una riga di codice è tutto ciò che serve (See it in action at jsFiddle):

$(arrayOfJQ_Objects).map (function() {return this.toArray(); }); 

Con conseguente questa console mostra in Firebug:

jQuery(div, span, li) 


Riferimento, anche jQuery's .toArray() function.

+17

l'esempio di jsfiddle è molto vicino a uccidere .. Scommetto solo per le 150 righe di codice per dimostrare $ .map() – JBeckton

+2

Funziona anche: '$ (arrayOfJQ_Objects) .map (function() {return this.get (0);}); 'o' $ (arrayOfJQ_Objects) .map (function() {return this.get();}); ' – Renato

+1

" Questa riga di codice è tutto ciò che serve "più le altre 149 righe di codice . Perché è stato accettato come risposta, quel muro di codice è orrendo. –

-2
$('li').each(function(){ 
    $(this).doSomething(); 

})

+0

Non capisco cosa stai cercando di ottenere con quella risposta. – fncomp

+0

Capisco cosa intendi, ma come fai a sapere che il set di 'li's è lo stesso del set che dovresti selezionare? – fncomp

+0

Stavo chiedendo di un gruppo di elementi che sono già selezionati e memorizzati in una variabile, sotto forma di un array, non come selezionare un insieme di elementi e fare qualcosa. –

0

si potrebbe fare qualcosa di simile:

var $temp = $(); 
$.each([$("li"), $("li"), $("li")], function(){ 
    $temp.push(this[0]); 
}) 

$ temp tutti gli elementi in un selettore jQuery

ma sono curioso quello che ti porta a questa situazione avere una matrice di diversi elementi jQuery. Sai che puoi selezionare diversi elementi usando una virgola? come $("li, ul > li:eq(0), div")

modifica come ha sottolineato Guffa, questo aggiunge solo il primo elemento di ogni sezione. .add() è una scelta migliore quindi .push() qui.

+0

sembra che abbiamo avuto la stessa idea. – fncomp

+0

Questo otterrebbe solo il primo elemento da ogni oggetto jQuery, e non vi è alcun metodo 'push' in jQuery. – Guffa

+0

o forse l'OP vorrebbe scegliere come target nested 'li'? come '$ (" li li li ")'? – jackJoe

16

Se quello che realmente dire è come convertire:

[$(a), $(b), $(c)] 

nel risultato di:

$(a, b, c) 

quindi è possibile utilizzare la funzione Add per aggiungere ogni oggetto jQuery per un altro oggetto jQuery:

var x = $(); // empty jQuery object 
$.each([$(a), $(b), $(c)], function(i, o) {x = x.add(o)}); 

A questo punto, x conterrà un oggetto jQuery combinato che è la combinazione del precedente oggetti jQuery a, b e c nella matrice.

Impossibile trovare il modo di farlo senza il ciclo each(). La funzione add() accetta un array di elementi DOM come argomento, ma (almeno secondo the documentation), non un array di oggetti jQuery.


Oppure, si potrebbe utilizzare questo, che sarebbe probabilmente un po 'più efficiente perché fa solo un nuovo oggetto jQuery alla fine:

$([$(".a"), $(".b"), $(".c")].reduce(function(result, current) { return result.concat(current.get())}, [])); 
+2

'add' restituisce una copia, quindi questo' O (n^2) '. –

1

Edit: Ho pensato jQuery supportato tutto Array metodi, ma anzi, quindi ecco una versione funzionante della mia soluzione iniziale, anche se è un po 'strano dal momento che sto attenendosi agli stessi metodi:

var set; // The array of jQuery objects, 
     // but make sure it's an Array. 
var output = set.pop(); 
$.each(set, function (_, item) { 
    return [].push.call(output, [].pop.call(item)); 
}); 
+0

cos'è '.pop()'? – meo

+0

Restituisce e rimuove l'ultimo elemento da una matrice. – fncomp

+0

Questo creerebbe solo un nuovo array che contiene esattamente lo stesso di quello vecchio. – Guffa

5

È possibile utilizzare il metodo add per copiare gli elementi in un oggetto jQuery su un altro.Ciò copierà tutti gli elementi da ciascuno degli oggetti jQuery nella matrice source nell'oggetto jQuery items:

// Create an empty jQuery object 
var items = $([]); 
// Add the elements from each jQuery object to it 
$.each(source, function(){ items = items.add(this); }); 

(Prima della versione 1.3.2 il metodo add non supporta l'aggiunta di un oggetto jQuery, in modo da sarebbe è necessario utilizzare items.add(this.get()); invece.)

+0

Che cosa c'è motivo per non fare 'var items = $()'? creare il tuo oggetto jQuery vuoto? – meo

+0

@meo: Funziona anche, ma solo per la versione 1.4 o successiva. – Guffa

+0

FYI, questa soluzione sembra funzionare solo quando sostituisco items.add (this); con items = items.add (this); Suppongo che .add() non cambi l'oggetto su cui è stato chiamato. –

1

Per aggiungere singolo elemento:

var $previousElements = $(); 
$previousElements.add($element); 

per convertire array jQuery insieme di elementi:

var myjQueryElementArray = [$element1, $element2, $elementN]; 
$(myjQueryElementArray).map (function() {return this.toArray(); }); 

a inserire matrice di elementi di elementi esistenti:

var $previousElements = $(), 
    myjQueryElementArray = [$element1, $element2, $elementN]; 

$previousElements.add($(myjQueryElementArray).map (function() {return this.toArray(); })); 
+0

al punto .. ottima risposta .. grazie per non collegare a 150 linee di codice js in jsfiddle solo per dimostrare .map() – JBeckton

1

Se Array.prototype.reduce() è supportato nel tuo ambiente.

var jQueryCollection = [$("a"), $("div")] 
          .reduce(function (masterCollection, collection) { 
           return masterCollection.add(collection); 
          }, $()); 

jsFiddle.

2

O semplicemente $(<array of jquery elements>);

cioè $([$("selector1"), $("selector2"), $("selector3"), ...]);

4

Un po 'più concisa rispetto alla risposta accettata, si può usare la $.fn.toArray come argomento passato alla $.fn.map:

var list = [$('<a>'), $('<b>'), $('<i>')]; 

$(list).map($.fn.toArray); 

O forse (questo è veramente inferiore, ma ha solo una chiamata di funzione nel codice):

$.fn.map.call(list, $.fn.toArray);