2013-04-25 14 views
10

Qual è la differenza tra l'utilizzo di document.head e l'utilizzo di document.getElementsByTagName("head")[0]? I test che ho eseguito hanno dimostrato che entrambi richiedono circa un millisecondo.document.head v. Document.getElementsByTagName ("head") [0]

Ho visto anche

document.head||document.getElementsByTagName("head")[0]; 

che mi avrebbe portato a credere che document.head è più veloce e l'altra è più più compatibile, tranne che i test ho smentito questa.

E se uno è più compatibile, perché usare anche l'altro?

Aggiornamento: I miei test erano sbagliati, come alcuni hanno sottolineato.

+0

Si può anche fare 'document.querySelector (" head ")'. È solo una questione di scelta. –

+0

Quasi non può diventare più veloce di avere un riferimento diretto. Quindi 'document.head' dovrebbe essere più veloce di una magnitudine, vedi http://jsperf.com/document-head-vs-getelementsbytagname – jAndy

risposta

10

L'utilizzo dell'operatore || è una forma di rilevamento di funzionalità. Se utilizzato, se il primo valore non è definito, restituisce quest'ultimo valore.

Così per

document.head || document.getElementsByTagName("head")[0]; 

il motivo è che se document.head non è supportato, almeno viene restituito il giusto valore.

Per quanto riguarda il test di velocità, un millisecondo è un tempo lungo. Dubito che ci sia voluto tanto tempo. In effetti, ho creato uno jsPerf per questo. Mostra che la funzione getElementsByTagName è circa l'80% più lenta.

+2

D'accordo che loro don ' t prendere lo stesso tempo, 'getElementsByTagName' diventa più lento man mano che aumenta la dimensione del DOM. E '1ms' è un segnale che è stato misurato male –

+0

Sì, stavo usando' console.time() 'in FF ... –

+1

@Sortofabeginner' console.time() 'è abbastanza buono per questo scopo, ma tu ' D devo misurare più di una volta per ottenere una precisione decente –

2

Questo è più di una questione di convenienza di uno di prestazioni (anche se document.head dovrebbe avere un beneficio trascurabile). Usa quello che vuoi, oppure, usa uno come fallback per l'altro (come fa il tuo codice di esempio). Avere il fallback è saggio, dal momento che document.head non è supportato in IE 6-8.

Non è probabile che lo getElementsByTagName sarà presto deprecato, quindi questo non è un ottimo esempio di quando è opportuno fornire un fallback. Si può tranquillamente usare la rotta più prolissa da sola e godere del supporto nel futuro.

I migliori esempi di questi tipi di cose sarebbero gli eventi e il modo in cui vengono passati nei browser moderni, rispetto ai browser più vecchi. Non è raro vedere qualcosa di simile:

function callback (event) { 
    var id = (event || window.event).target.id; 
} 

In questo caso, però, la porzione window.event è necessario per il supporto legacy. Se l'oggetto event è undefined, si assume che l'evento sia membro dell'oggetto window. Man mano che i browser maturano, window.event cessa di essere una cosa, e questi test restituiscono all'unanimità event.target.id invece.

Anche in questo caso, il tuo caso è un po 'diverso come getElementsByTagName probabilmente non sarà mai deprecato o svanire come fatto window.event.

+0

Non credo che una penalizzazione delle prestazioni dell'83% sia * solo * una questione di convenienza. http://jsperf.com/document-head-vs-getelementsbytagname – jAndy

+2

@jAndy ~ 83% su questa scala è trascurabile. Questo non è il tipo di preoptimizzazione di cui gli sviluppatori web devono preoccuparsi, in generale. – Sampson

+2

Non sono d'accordo. Mi aspetto di interrogare gli elementi DOM il più velocemente possibile, dal momento che questo tipo di operazione potrebbe verificarsi migliaia di volte. – jAndy

4

Secondo MDN, document.head guadagnato solo il supporto a IE 9, in modo da utilizzare l'altro metodo come ripiego ti protegge dal browser incompatibilità

+0

Ma se 'document.getElementsByTagName (" head ") [0]' è più compatibile, perché usare 'document.head'? –

+0

@Sortofabeginner Perché è più breve e più facile da leggere. Esistono diversi modi per interrogare il DOM. In alcuni casi, * l'altro modo * può diventare deprecato. Non sospetto che ciò accadrà in questo caso però. – Sampson

1

Proprio convenienza, perché si suppone solo per avere uno per pagina. Proprio come c'è un collegamento diretto a document.body, anche se lo standard document.body è standard e non è necessario il fallback.

document.body || document.getElementsByTagName("body")[0] 

Non utilizzare document.head a meno che non supporti solo IE9 +. Fino ad allora, vorrei bastone a document.getElementsByTagName("head")[0]

Se si desidera una versione che non c'è bisogno di cambiare col passare del tempo, è possibile effettuare le seguenti operazioni nella parte superiore dello script

document.head = document.head || document.getElementsByTagName("head")[0]; 

questo modo puoi semplicemente cambiare quella posizione quando lasci il supporto per IE8 (o potresti lasciarlo lì perché non fa male, ma sarà un codice morto).Il codice precedente si assicurerà inoltre di interrogare il DOM solo una volta

+0

Hai messo il corpo al posto della testa. –

+0

@Sortofabeginner Grazie, risolto. –

+1

L'hai risolto solo in una posizione: ci sono molte altre istanze. –