2011-08-23 10 views
29

Si me quedo este código -Usando jQuery para buscar una cadena de HTML

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

no da resultados positivos devueltos, si funciono este código -

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

Entonces consigo un único resultado devuelto - el div interno (<div class="bar"></div>). Hubiera esperado que el primer fragmento de código devolviera un único resultado y el segundo fragmento dos resultados.

Del mismo modo, este código no devuelve ningún resultado -

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

pero este código alertas 'div' dos veces -

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

Teniendo en cuenta el resultado del segundo fragmento, lo que habría esperado el primer código fragmento para devolver dos resultados. ¿Podría alguien explicar por qué obtengo los resultados que obtendré?

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

+0

he cambiado '' console.log' a alert', y alertado '[object Object] ', por lo que debe haber encontrado algo ... –

+2

@Eran Zimmerman: Esto se debe a que jQuery siempre devuelve un objeto, independientemente de la cantidad de coincidencias encontradas para el selector. –

+2

Supongo que [Objeto objeto] se refiere a la matriz vacía que jQuery devuelve. – ipr101

Respuesta

33

Vamos a dividir esta pregunta en dos partes.

Primero:

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

y

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

no funcionan porque según el jQuery() docs:

Al pasar en HTML complejo, algunos navegadores no pueden generar un DOM eso replica exactamente la fuente HTML proporcionada. Como se mencionó, usamos la propiedad .innerHTML del navegador para analizar el HTML pasado e insertarlo en el documento actual. Durante este proceso, algunos navegadores filtran ciertos elementos como <html>, <title> o <head> elementos. Como resultado, los elementos insertados pueden no ser representativos de la secuencia original pasada.

  • En el primer bloque de código, sus <html>, <head> y <body> etiquetas están siendo despojados, y <div class="bar"></div> restos. find solo busca en el resultado <div>, y no puede encontrar nada.
  • En el segundo bloque de código, las etiquetas <html>, <head> y <body> se están eliminando y <div><div class="bar"></div></div> permanecen. find busca dentro del resultado y encuentra un solo <div>.

En cuanto a su segunda parte:

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

En primer lugar, da jQuery una cadena, que se necesita y lo hace en un objeto jQuery con los dos <div> 's. Luego, find busca en cada <div>, no encuentra nada y no arroja resultados.

A continuación, en

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

each bucles a través del objeto jQuery, teniendo cada una de las dos creadas <div> 's, y alerta a su nombre de nodo. Por lo tanto, obtienes dos alertas.

2

.find en el tercer ejemplo, las búsquedas de los niños en cada elemento coincidente. Dentro de su div s no hay niños div (no tienen hijos), por lo que .find(anything) no devolverá ningún elemento.

.each, por otro lado, itera sobre los elementos de corriente en el conjunto, que sí incluye los div s (hay dos elementos coincidentes - los div s).

En cuanto a <html> en su primer ejemplo, no estoy seguro; quizás no esté autorizado a crear un segundo elemento <html> después de que la página se haya cargado. $('<html><head></head><body><div class="bar"></div></body></html>'); solo devuelve el div para que .find no devuelva nada.

+2

jQuery (o más exactamente, el navegador) elimina las etiquetas 'html',' head' y 'body' y solo mantiene el contenido del 'cuerpo'. –

+0

@Felix Kling: Gracias, es bueno saberlo. Eso puede ser frustrante. – pimvdb

13

la respuesta es muy simple. cuando haces un objeto usando jQuery (html) crea una jerarquía de nodos, y cuando encuentras un nodo como 'div', busca en toda la jerarquía, excepto en los elementos raíz, y en tu primer ejemplo, no tienes el 'div' infantil nodos. Y en su segundo ejemplo, solo tiene un nodo secundario 'div'.

así que si mantiene un nodo raíz adicional en toda la jerarquía, entonces puede encontrar todos sus nodos fácilmente. como

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

así es como debe hacerse. La respuesta aceptada no funcionará si hay más de un elemento raíz. – ProblemsOfSumit

3

La forma más sencilla es la siguiente:

dado una cadena:

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

Buscar el div con la barra de clase:

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

O todos los divs:

$(html).filter('div') 

devuelve el objeto con la clase bar

+0

¡genial! ¡me salvaste el día! –

Cuestiones relacionadas