2010-03-28 17 views
6

Mi proyecto actual consiste en reunir contenido de texto de un elemento y todos sus descendientes, en función de un selector provisto.JavaScript: ¿Cómo obtener texto de todos los descendientes de un elemento sin tener en cuenta los scripts?

Por ejemplo, cuando se suministra el selector #content y ejecutarse sobre este HTML:

<div id="content"> 
    <p>This is some text.</p> 
    <script type="text/javascript"> 
    var test = true; 
    </script> 
    <p>This is some more text.</p> 
</div> 

mi guión volvería (después de un poco de limpieza de espacios en blanco):

Esto es un texto. var test = verdadero; Este es un poco más de texto.

Sin embargo, necesito ignorar los nodos de texto que se producen dentro de los elementos <script>.

Este es un extracto de mi código actual (técnicamente, de que coincida basa en uno o selectores más proporcionadas):

// get text content of all matching elements 
for (x = 0; x < selectors.length; x++) { // 'selectors' is an array of CSS selectors from which to gather text content 
    matches = Sizzle(selectors[x], document); 
    for (y = 0; y < matches.length; y++) { 
    match = matches[y]; 
    if (match.innerText) { // IE 
     content += match.innerText + ' '; 
    } else if (match.textContent) { // other browsers 
     content += match.textContent + ' '; 
    } 
    } 
} 

Es un poco demasiado simplista, ya que sólo devuelve todos los nodos de texto dentro del elemento (y sus descendientes) que coincide con el selector provisto. La solución que estoy buscando devolvería todos los nodos de texto, excepto aquellos que están dentro de los elementos <script>. No es necesario que sea especialmente de alto rendimiento, pero sí necesito que sea finalmente compatible con varios navegadores.

Supongo que tendré que recorrer de algún modo todos los elementos secundarios del elemento que coincida con el selector y acumular todos los nodos de texto distintos de los que están dentro de los elementos <script>; no parece que haya ninguna forma de identificar JavaScript una vez que ya se ha incorporado a la cadena acumulada de todos los nodos de texto.

No puedo usar jQuery (por motivos de rendimiento/ancho de banda), aunque es posible que hayas notado que utilizo su motor de selector Sizzle, por lo que la lógica de selector de jQuery está disponible.

¡Gracias de antemano por cualquier ayuda!

Respuesta

8
function getTextContentExceptScript(element) { 
    var text= []; 
    for (var i= 0, n= element.childNodes.length; i<n; i++) { 
     var child= element.childNodes[i]; 
     if (child.nodeType===1 && child.tagName.toLowerCase()!=='script') 
      text.push(getTextContentExceptScript(child)); 
     else if (child.nodeType===3) 
      text.push(child.data); 
    } 
    return text.join(''); 
} 

O, si se le permite cambiar el DOM para eliminar los elementos <script> (que no suele tener efectos secundarios notables), más rápido:

var scripts= element.getElementsByTagName('script'); 
while (scripts.length!==0) 
    scripts[0].parentNode.removeChild(scripts[0]); 
return 'textContent' in element? element.textContent : element.innerText; 
+0

¡Impresionante, gracias, bobince! Fui con el primer enfoque, probablemente tengas razón en que eliminar los elementos '

2

EDITAR:

Bueno, primero déjeme decir que no estoy demasiado familiarizado con chisporroteo en su solitaria, jsut dentro de las bibliotecas que lo utilizan ... Dicho esto ..

Si tuviera que hacer esto Haría algo como:

var selectors = new Array('#main-content', '#side-bar'); 
function findText(selectors) { 
    var rText = ''; 
    sNodes = typeof selectors = 'array' ? $(selectors.join(',')) : $(selectors); 
    for(var i = 0; i < sNodes.length; i++) { 
     var nodes = $(':not(script)', sNodes[i]); 
     for(var j=0; j < nodes.length; j++) { 
     if(nodes[j].nodeType != 1 && node[j].childNodes.length) { 
      /* recursion - this would work in jQ not sure if 
       * Sizzle takes a node as a selector you may need 
       * to tweak. 
       */ 
      rText += findText(node[j]); 
     } 
     } 
    } 

    return rText; 
} 

No he probado nada de eso, pero debería darle una idea. Con suerte tubería alguien más lo hará con más sentido :-)


Cant que acaba de agarrar el nodo padre y comprueba la nodeName en su bucle ... como:

if(match.parentNode.nodeName.toLowerCase() != 'script' && match.nodeName.toLowerCase() != 'script') { 
    match = matches[y]; 
    if (match.innerText) { // IE 
     content += match.innerText + ' '; 
    } else if (match.textContent) { // other browsers 
     content += match.textContent + ' '; 
    } 
} 

supuesto jQuery soporta el not() sintaxis en los selectores, ¿podría simplemente hacer $(':not(script)')?

+0

Gracias prodigitalson - no estoy seguro Sin embargo, esto lograría mi objetivo. Podría haber sido un poco vago en mi ejemplo de código (simplemente lo he editado): lo que hace es atravesar una matriz de selectores CSS, y para cada uno que coincide con un nodo DOM, simplemente obtiene el texto interno (IE) o contenido de texto (otro) propiedad de ese nodo. En realidad, no recorre los elementos de los niños. Sin embargo, creo que este último es probablemente la mejor manera de hacerlo: recorrer todos los descendientes del elemento coincidente, sin tener en cuenta los nodos de texto en

  • 11. ¿Necesita shebang en todos los scripts bash?
  • 12. ¿Puedo forzar a los descendientes a tener un constructor sin parámetros?
  • 13. ¿Cómo puedo obtener/enumerar/ver todos los descendientes de una confirmación con git (o gitk)?
  • 14. Cómo añadir texto a todos los valores de JavaScript matriz
  • 15. En GWT, ¿cómo puedo obtener todos los atributos de un elemento en el HTML DOM?
  • 16. Comparación de cadenas para tener en cuenta los números
  • 17. Cómo obtener todos los elementos dentro de "div" que comienza con un texto conocido
  • 18. ¿Es posible añadir a innerHTML sin destruir los detectores de eventos de los descendientes?
  • 19. Obtener todos los elementos de opciones seleccionados de todos los elementos seleccionados en un formulario
  • 20. ¿Cómo busco solo los elementos secundarios de un XDocument, en lugar de todos sus descendientes?
  • 21. ¿Cómo obtener los valores de estilo de un elemento HTML en javascript?
  • 22. Consulta de XPath con predicados descendientes y descendientes de texto()
  • 23. Cómo rastrear o depurar todos los eventos de javascript disponibles
  • 24. ¿Deberían todos los objetos tener una interfaz y todos los objetos unidos sin apretar?
  • 25. cómo obtener todos los UILabels dentro de un UIView
  • 26. ¿Cómo puedo vincular todos los eventos en un elemento DOM?
  • 27. Cuenta todos los elementos en la lista de lista anidada arbitraria sin recursión
  • 28. obtener el texto de un elemento sin elementos secundarios en javascript
  • 29. ¿Cómo puedo incluir todos los archivos JavaScript en un directorio a través de un archivo JavaScript?
  • 30. ¿Cómo puedo encontrar todos los nodos de texto entre los nodos de elementos con Javascript/JQuery?