2010-05-14 19 views
9

Estoy buscando una forma de recopilar todo el texto en un conjunto envuelto jQuery, pero necesito crear espacios entre nodos hermanos que no tienen texto nodos entre ellos.Uso de jQuery para reunir todos los nodos de texto de un conjunto envuelto, separados por espacios

Por ejemplo, considere este código HTML:

<div> 
    <ul> 
    <li>List item #1.</li><li>List item #2.</li><li>List item #3.</li> 
    </ul> 
</div> 

Si simplemente uso el método de jQuery text() para recoger el contenido del texto de la <div>, como por ejemplo:

var $div = $('div'), text = $div.text().trim(); 

alert(text); 

que produce el texto siguiente:

Lista de elementos # 1.Lista artículo # 2.Lista artículo # 3.

porque no hay espacios en blanco entre cada elemento <li>. Lo que realmente estoy buscando es esto (observe el espacio simple entre cada frase):

Artículo de la lista # 1. Lista elemento # 3. Lista elemento # 3.

Esto me sugiere que necesito atravesar los nodos DOM en el conjunto envuelto, agregando el texto para cada uno a una cadena, seguido de un espacio. He probado el siguiente código:

var $div = $('div'), text = ''; 

$div.find('*').each(function() { 
    text += $(this).text().trim() + ' '; 
}); 

alert(text); 

pero esto produjo el siguiente texto:

Este es elemento de la lista # 1. Esta es la lista de elementos # 2. Esta es la lista de elementos # 3. Este es el elemento de lista n. ° 1. Este es el elemento de lista n. ° 2. Este es el elemento de lista n. ° 3.

Supongo que esto se debe a que estoy iteración a través de todos los descendientes de <div> y añadiendo el texto, por lo que estoy recibiendo los nodos de texto dentro de tanto <ul> y cada uno de sus hijos <li>, lo que lleva al texto duplicado.

Creo que probablemente podría encontrar/escribir una función JavaScript simple para recorrer recursivamente el DOM del conjunto envuelto, reuniendo y añadiendo nodos de texto, pero ¿hay alguna manera más sencilla de hacerlo con jQuery? La consistencia entre navegadores es muy importante.

¡Gracias por cualquier ayuda!

Respuesta

7

jQuery se ocupa principalmente de elementos, sus poderes de nodo de texto son relativamente débiles. Puede obtener una lista de todos los niños con contents(), pero igual tendría que recorrer los tipos de comprobación, así que eso no es realmente diferente de simplemente usar DOM childNodes. No hay un método para recursivamente obtener nodos de texto por lo que tendría que escribir algo usted mismo, por ejemplo.algo así como:

function collectTextNodes(element, texts) { 
    for (var child= element.firstChild; child!==null; child= child.nextSibling) { 
     if (child.nodeType===3) 
      texts.push(child); 
     else if (child.nodeType===1) 
      collectTextNodes(child, texts); 
    } 
} 
function getTextWithSpaces(element) { 
    var texts= []; 
    collectTextNodes(element, texts); 
    for (var i= texts.length; i-->0;) 
     texts[i]= texts[i].data; 
    return texts.join(' '); 
} 
+0

¡Impresionante, esto funcionó como un amuleto! Muchas gracias, no sé qué haría sin ti, bobince. ;-) – Bungle

+0

funciona muy bien en 'Ndumiso Mlilo agregó una nueva foto. '^ _^ – evandrix

0

Puede utilizar el método jQuery contents() para obtener todos los nodos (incluidos los nodos de texto), luego filtrar su conjunto a solo los nodos de texto.

$("body").find("*").contents().filter(function(){return this.nodeType!==1;}); 

Desde allí puede crear la estructura que necesite.

+2

Gracias por la respuesta, pero esto no funcionó para mí. ¿Podría ampliar su código de muestra? Además, creo que 'contents()' solo atraviesa hijos inmediatos del conjunto envuelto (ver http://api.jquery.com/contents/), no todos los descendientes. – Bungle

+0

@Bungle, es cierto, 'contents()' no recopila los nodos recursivamente sino solo los descendientes inmediatos. – acme

+0

falla en 'Ndumiso Mlilo agregó una nueva foto. ' – evandrix

2

Ésta es la solución más simple que podía pensar:

$("body").find("*").contents().filter(function(){return this.nodeType!==1;}); 
+0

¡solución muy elegante! – acme

+0

falla en 'Ndumiso Mlilo agregó una foto nueva. ' – evandrix

+0

produce' agregó una nueva foto. Ndumiso Mlilo' en lugar de 'Ndumiso Mlilo agregó una foto nueva. – evandrix

Cuestiones relacionadas