2012-01-09 15 views
10

Sto lavorando con una dashboard di div e ogni div ha un albero di cui sono i pulsanti. Ogni volta devo sapere qual è l'id di quel div così sto usando parent() un sacco.Parent(), alternativa più veloce?

Per lo più sto facendo $(this).parent().parent().parent() per trovare l'ID di div in modo da poter impostare le variabili ad esso. L'app è basata sull'ID di ogni div.

È considerato lento utilizzare parent() fino a 3 volte ma praticamente su ogni funzione?

C'è qualche altra alternativa?

Sto cercando qualcosa di simile a uno stile di riferimento che mostri ciò che è più veloce.

Ecco un esempio della struttura:

<div id="6179827893" class="dashdiv"> 
    <div class="buttons"> 
    <li><a href="#" class="btn1">Button 1</a></li> 
    <li><a href="#" class="btn2">Button 2</a></li> 
    <li><a href="#" class="btn3">Button 3</a></li> 
    <li><a href="#" class="btn4">Button 4</a></li> 
    <li><a href="#" class="btn5">Button 5</a></li> 
    <li><a href="#" class="btn6">Button 6</a></li> 
    </div> 
    <div class="dashcontent"> 

    .... 

    </div> 
</div> 
+0

forse il: contiene selettore è una soluzione. http://api.jquery.com/contains-selector/ – ggzone

+0

Conosci forse il nome della classe CSS del genitore? –

risposta

17

Hai alcune opzioni per ottenere lo stesso effetto.

Riferimento: http://jsperf.com/parents-method. Secondo questo punto di riferimento, il mio metodo è approssimativamente 100 volte più veloce del tuo metodo.

Method (see below) : Operations per second (higher is better) 
parentNode3x  : 4447k 
$(parentNode3x) : 204K 
$().closest  : 35k 
$().parents  : 9k 
$().parent()3x  : 44k 

// Likely the fastest way, because no overhead of jQuery is involved. 
var id = this.parentNode.parentNode.parentNode.id; 

// Alternative methods to select the 3rd parent: 
$(this.parentNode.parentNode.parentNode) // Native DOM, wrapped in jQuery 

// Slowpokes 
$(this).closest('.dashdiv')    // Hmm. 
$(this).parents('.dashdiv:first')  // Hmm... 
+0

La tua seconda opzione è più veloce di quella che ho? Suppongo che parentNode significhi parent() – jQuerybeast

+0

@jQuerybeast Ho incluso un benchmark: http://jsperf.com/parents-method –

+0

Grazie e per il benchmark. Praticamente quello che stavo cercando – jQuerybeast

8

si potrebbe essere meglio utilizzare .closest(), in questo modo: $(this).closest('.dashdiv')

Non è più veloce dal punto di vista di un motore, visto che tu sei continua a scorrere attraverso i livelli DOM, ma è più chiaro per un nuovo arrivato e per un codice più breve.

COMMENTO

Se si tratta di velocità pura che stai dopo, si potrebbe anche saltare jQuery del tutto e utilizzare node.parentNode invece. Ma questo sta entrando in questioni negative di cicli di conteggio, e penso che sia accademico.

Se si sta scrivendo codice ad alte prestazioni per grandi produzioni, come un motore di ricerca commerciale o un fornitore di servizi webmail, il conteggio dei cicli è importante perché ogni piccola ottimizzazione viene moltiplicata migliaia di volte. Con tutto il dovuto rispetto, dubito che tu stia scrivendo quel tipo di codice.

Se stai scrivendo qualcosa che sarà colpito da poche persone alla volta, al massimo, allora le piccole ottimizzazioni sono un esercizio intellettuale che non influirà sui risultati in alcun modo evidente. Dovresti migliorare l'efficienza del tuo codice di centinaia di millisecondi prima che qualsiasi utente inizi a notare, e questo codice non lo farà.

Invece, è molto più importante pensare al prossimo sviluppatore che guarderà il tuo codice. Per questo sviluppatore, è importante avere un codice chiaro e ben scritto che comunichi immediatamente ciò che sta facendo. Catene di metodi di sfocatura degli occhi come parent().parent().parent() possono oscurare e confondere altri sviluppatori, per non dire di node.parentNode.parentNode.parentNode

- che è il motivo per cui .closest() è stato creato in primo luogo. È chiaro, conciso e non notevolmente meno efficiente delle catene che sostituisce. 999 volte su mille, è il modo in cui dovresti andare.

+0

più vicino non è considerato più veloce. jQuery deve cercare il più vicino dove i genitori non lo fanno – jQuerybeast

+0

Sì, quello era il mio pensiero. Ma penso che ci sia un piccolo sacrificio da fare qui in cambio di un codice più chiaro e più conciso. Se sei alla ricerca della pura velocità, potresti anche saltare jQuery interamente e usare ['node.parentNode'] (https://developer.mozilla.org/En/DOM/Node.parentNode). – Blazemonger

+0

Grazie. Bene risposto La risposta di Rob selezionata come quella che userò e per il benchmark – jQuerybeast

2

In primo luogo, non ottimizzare in modo prematuro. Se non sta causando un problema (e testare accuratamente con tutti i mezzi, attraverso una gamma di piattaforme), non preoccuparti.

C'è una possibile ottimizzazione: utilizzare native proprietà DOM:

var id = this.parentNode.parentNode.parentNode.id; 

Nota che il modo jQuery più bello per fare questo (che sarà più lento, ma che non può essere un problema) è con closest:

$(this).closest('div.dashdiv').prop('id'); 
+0

Sono consapevole del più vicino ma è probabilmente il più lento di tutti e man mano che l'app diventa sempre più grande sarà un dolore. Suppongo che, come dichiarato da Rob W, parentNode sarà il più veloce giusto? – jQuerybeast

+1

@jQuerybeast Sì: [è ciò che jQuery utilizza internamente] (https://github.com/jquery/jquery/blob/master/src/traversing.js#L179). – lonesomeday

+0

Ha! Bello sul link. Considerando il tuo 'non ottimizzare in modo prematuro' Non sono sicuro se dovrei scambiare genitore() con parentNode o lasciarlo così com'è – jQuerybeast

1

Se i gestori sono attualmente sul <a> elementi, metterli sul .dashdiv elementi invece.

Quindi è possibile eseguire this.id se lo e.target era un elemento <a>.

$('.dashdiv').click(function(e) { 
    if(e.target.nodeName.toLowerCase() === 'a') { 
     alert(this.id); 
    } 
});