2011-08-23 7 views
29

Se corro questo codice -utilizzando jQuery per cercare una stringa di codice HTML

var html= '<html><head></head><body><div class="bar"></div></body></html>'; 
console.log($(html).find('div')); 

non ottengo risultati restituiti, se corro questo codice -

var html= '<html><head></head><body><div><div class="bar"></div></div></body></html>'; 
console.log($(html).find('div')); 

Poi ho un unico risultato restituito - il div interno (<div class="bar"></div>). Mi sarei aspettato che il primo snippet di codice restituisse un singolo risultato e il secondo frammento di due risultati.

Allo stesso modo, questo codice ha prodotto alcun risultato -

var code = $("<div id='foo'>1</div><div id='bar'>2</div>"); 
console.log(code.find('div')); 

ma questo codice avvisi 'div' due volte -

var code = $("<div id='foo'>1</div><div id='bar'>2</div>"); 
code.each(function() { 
    alert(this.nodeName); 
}) 

Dato il risultato del secondo frammento di, mi sarei aspettato il primo codice snippet per restituire due risultati. Qualcuno potrebbe spiegare perché sto ottenendo i risultati che sto ottenendo?

http://jsfiddle.net/ipr101/GTCuv/

+0

ho cambiato 'console.log' a' alert', ed avvisato '[object Object]', in modo che deve aver trovato qualcosa ... –

+2

@Eran Zimmerman: Questo perché jQuery restituisce sempre un oggetto, indipendentemente dalla quantità di corrispondenze trovate per il selettore. –

+2

Suppongo che [oggetto oggetto] si riferisca alla matrice vuota restituita da jQuery. – ipr101

risposta

33

Dividiamo questa domanda in due parti.

Primo:

var html= '<html><head></head><body><div class="bar"></div></body></html>'; 
console.log($(html).find('div')); 

e

var html= '<html><head></head><body><div><div class="bar"></div></div></body></html>'; 
console.log($(html).find('div')); 

non funzionano perché secondo l'jQuery() docs:

Quando si passa nel complesso HTML, alcuni browser potrebbero non generare un DOM che replica esattamente la sorgente HTML fornita. Come accennato, utilizziamo la proprietà .innerHTML del browser per analizzare l'HTML passato e inserire nel documento corrente. Durante questo processo, alcuni browser filtrano alcuni elementi come <html>, <title> o <head> elementi. Di conseguenza, gli elementi inseriti potrebbero non essere rappresentativi della stringa originale passata.

  • Nel primo blocco di codice, i vostri <html>, <head> e <body> tag sono sempre messi a nudo, e <div class="bar"></div> resti. find cerca solo all'interno dello <div> risultante e non riesce a trovare nulla.
  • Nel secondo blocco di codice, i tag <html>, <head> e <body> vengono eliminati e rimane <div><div class="bar"></div></div>. find cerca all'interno del risultato e trova un singolo <div>.

quanto riguarda la seconda parte:

var code = $("<div id='foo'>1</div><div id='bar'>2</div>"); 
console.log(code.find('div')); 

Per prima cosa dare jQuery una stringa, che prende e fa in un oggetto jQuery con i due <div> s'. Quindi, le ricerche find in ogni <div> non trovano nulla e non restituiscono alcun risultato.

successiva, in

var code = $("<div id='foo'>1</div><div id='bar'>2</div>"); 
code.each(function() { 
    alert(this.nodeName); 
}) 

each passanti attraverso l'oggetto jQuery, prendendo ciascuno dei due creati <div> 's, e avvisa il nome del nodo. Pertanto, ricevi due avvisi.

2

.find nel terzo esempio, ricerche i bambini in ogni elemento abbinato. All'interno dei tuoi div s non ci sono bambini div (non hanno figli), quindi .find(anything) non restituirà alcun elemento.

.each, d'altra parte, itera sugli elementi correnti nel set, che include le div s (vi sono due elementi accoppiati - i div s).

Per quanto riguarda il <html> nel tuo primo esempio, non sono sicuro - forse non ti è permesso creare un secondo elemento <html> dopo che la pagina è stata caricata. $('<html><head></head><body><div class="bar"></div></body></html>'); restituisce solo il div quindi .find non restituisce nulla.

+2

jQuery (o più accuratamente, il browser) rimuove i tag 'html',' head' e 'body' e mantiene solo il contenuto' body'. –

+0

@Felix Kling: Grazie, buono a sapersi. Questo può essere frustrante. – pimvdb

13

la risposta è molto semplice. quando costruisci l'oggetto usando jQuery (html), crea una gerarchia di nodi e quando trovi un nodo come "div", cerca in tutta la gerarchia tranne gli elementi radice e, nel tuo primo esempio, non hai figli "div" i nodi. E nel tuo secondo esempio hai un solo nodo 'div' figlio.

quindi, se si mantiene un nodo radice supplementare nell'intera gerarchia, è possibile trovare facilmente tutti i nodi. come

var html= '<html><head></head><body><div class="bar"></div></body></html>'; 
console.log($('<div></div>').append(html).find('div')); 

var html= '<html><head></head><body><div><div class="bar"></div></div></body></html>'; 
console.log($('<div></div>').append(html).find('div')); 
+1

questo è come dovrebbe essere fatto. La risposta accettata non funzionerà se ci sono più di 1 elemento radice. – ProblemsOfSumit

3

Il modo più semplice è la seguente:

dando la stringa:

var html= '<html><head></head><body><div class="bar"></div></body></html>'; 

Cerca il div con la barra classe:

$(html).filter('.bar') 

O tutti div:

$(html).filter('div') 

restituisce l'oggetto con la classe bar

+0

fantastico! risparmi la mia giornata! –