jQuery primo figlio di "questo"


317

Sto cercando di passare "questo" da un intervallo di clic a una funzione jQuery che può quindi eseguire jQuery sul primo figlio dell'elemento selezionato. Non riesco a farlo bene ...

<p onclick="toggleSection($(this));"><span class="redClass"></span></p>

Javascript:

function toggleSection(element) {
  element.toggleClass("redClass");
}

Come posso fare riferimento a: first-child of element?


4
Se stai usando jQuery, perché non associ anche i gestori di eventi usando jQuery?
— Vivin Paliath,

2
perché i gestori di eventi bind devono essere inizializzati in document.ready () che aggiunge un hit di prestazione (questa è un'app per IE6). oppure c'è un'altro modo?
— macca1,

Hm .. non ne sono sicuro. Associare usando jQuery è il modo standard (se stai già usando jQuery). Che tipo di prestazioni hai riscontrato durante l'utilizzo jQuery(document).ready(...)?
— Vivin Paliath,

È una grande applicazione con oltre 7 sviluppatori. In origine erano passati più di 4 secondi prima che provassi a ripulirlo un po '. Quindi preferirei evitare di aggiungere altro quando non devo :)
— macca1

Risposte:


482

Se si desidera applicare un selettore al contesto fornito da un set jQuery esistente, provare la funzione find () :

element.find(">:first-child").toggleClass("redClass");

Jørn Schou-Rode ha notato che probabilmente vuoi solo trovare il primo discendente diretto dell'elemento di contesto, quindi il selettore figlio (>). Sottolinea inoltre che è possibile utilizzare la funzione children () , che è molto simile a find () ma cerca solo un livello in profondità nella gerarchia (che è tutto ciò che serve ...):

element.children(":first").toggleClass("redClass");

1
Grazie! funziona perfettamente. Immagino che funzioneranno anche gli altri modi elencati di seguito.
— macca1,

6
Credo che effettui find()ricerche in tutti i discendenti e :first-childpossa corrispondere a un elemento per genitore. Pertanto, è possibile che questa query restituisca diversi elementi. O mi sbaglio?
— Jørn Schou-Rode,

19
So che questa è una vecchia domanda / risposta, ma l'utilizzo del selettore ">" senza un genitore in quel selettore è deprezzato (ad esempio, ">: firstchild") a partire da jQuery 1.8. Suggerisco invece di utilizzare element.children(":first-child")oelement.children().first();
— Kevin B,

3
@KevinB a quanto pare hanno deciso di non deprecarlo dopo tutto
— Alnitak,

1
l'approccio migliore NON sarebbe quello di iterare su tutti gli elementi e quindi scegliere il primo, come alcuni hanno suggerito qui. Questo sarebbe MALE.
— vsync,


51

Ho aggiunto il test jsperf per vedere la differenza di velocità per diversi approcci per ottenere il primo figlio (totale 1000+ bambini)

dato, notif = $('#foo')

modi jQuery:

  1. $(":first-child", notif) - 4.304 ops / sec - più veloce
  2. notif.children(":first") - 653 operazioni / sec - 85% più lento
  3. notif.children()[0] - 1.416 operazioni / sec - 67% più lento

Modi nativi:

  1. JavaScript nativo ' ele.firstChild- 4.934.323 ops / sec (tutti gli approcci precedenti sono più lenti del 100% rispetto a firstChild)
  2. Ele DOM nativo di jQery: notif[0].firstChild- 4.913.658 ops / sec

Quindi, i primi 3 approcci jQuery non sono raccomandati, almeno per il primo figlio (dubito che sarebbe così anche per molti altri). Se si dispone di un oggetto jQuery e è necessario ottenere il primo figlio, quindi ottenere l'elemento DOM nativo dall'oggetto jQuery, utilizzando il riferimento di matrice [0] (consigliato) oe .get(0)utilizzare ele.firstChild. Ciò fornisce gli stessi risultati identici del normale utilizzo di JavaScript.

tutti i test vengono eseguiti in Chrome Canary build v15.0.854.0


20
In realtà, firstChildnon darà gli stessi risultati delle children()query di jQuery o dei selettori. firstChildincluderà nodi di testo raramente desiderati. La contents()funzione di jQuery li includerà, ma children()non lo farà. Supporto per i browser più recenti firstElementChildche fornirà il primo elemento figlio, ma IE <9 non lo supporta. Quindi, se lo usi firstChilddevi trovare manualmente il primo figlio nodo non testuale.
— Max

1
$(":first-child", notif)dovrebbe essere $(":first", notif)per il comportamento previsto. Il primo restituirà tutti i discendenti degli elementi del primo figlio.
— Drazen Bjelovuk,

18
element.children().first();

Trova tutti i bambini e ottieni prima di loro.


1
Di gran lunga il metodo più semplice e più efficiente di .children(':first').
— Gras Double

3
Come è più efficiente? Sembra che prende tutti i bambini, quindi prende il primo, invece di ottenere solo il primo figlio.
— Anthony McGrath,

9

Hai provato

$(":first-child", element).toggleClass("redClass");

Penso che tu voglia impostare il tuo elemento come contesto per la tua ricerca. Potrebbe esserci un modo migliore per farlo che qualche altro guru di jQuery salterà qui e ti lancerà fuori :)


3
questo fallirà se elementha dei nipoti
— Alnitak,

4

Ho appena scritto un plug-in che utilizza .firstElementChildse possibile e, se necessario, ricorre all'iterazione su ogni singolo nodo:

(function ($) {
    var useElementChild = ('firstElementChild' in document.createElement('div'));

    $.fn.firstChild = function () {
        return this.map(function() {
            if (useElementChild) {
                return this.firstElementChild;
            } else {
                var node = this.firstChild;
                while (node) {
                    if (node.type === 1) {
                        break;
                    }
                    node = node.nextSibling;
                }
                return node;
            }
        });
    };
})(jQuery);

Non è veloce come una soluzione DOM pura, ma nei test jsperf con Chrome 24 era un paio di ordini di grandezza più veloce di qualsiasi altro metodo basato su selettori jQuery.


1
Mi piace questo plugin - ma ci sono 2 problemi: 1) Lo script del plugin non può essere incluso nella testa perché document.bodynon è ancora inizializzato, 2) Le prestazioni sono solo molto meglio delle alternative se il numero di nodi figlio è molto alto. Solo per alcuni bambini (diciamo meno di 10) $('>:first-child',context)è un po 'più veloce. Solo il numero di bambini influenza le prestazioni, non la profondità.
— codefactor

@codefactor buon punto a riguardo document.body- lo esaminerò.
— Alnitak,

4

puoi usare DOM

$(this).children().first()
// is equivalent to
$(this.firstChild)


1

per favore usalo come questa prima cosa dai un nome di classe per taggare p come "myp"

quindi utilizzare il seguente codice

$(document).ready(function() {
    $(".myp").click(function() {
        $(this).children(":first").toggleClass("classname"); // this will access the span.
    })
})

-3

Se vuoi il primo figlio immediato, ti serve

    $(element).first();

Se vuoi un primo elemento particolare nel dom dal tuo elemento, usa di seguito

    var spanElement = $(elementId).find(".redClass :first");
    $(spanElement).addClass("yourClassHere");

prova: http://jsfiddle.net/vgGbc/2/


11
questo è solo sbagliato - se elementè un nodo DOM allora $(element).first()è equivalente $(element), non il suo primo figlio.
— Alnitak,

1
D'accordo, se element è un nodo DOM $ (element) .first () equivale a $ (element) questo mi ha causato un problema con l'associazione knockoutJS
— drgn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.