2012-05-24 9 views
28

Duplicar posible:
getElementsByTagName() equivalent for textNodesBuscar todos los nodos de texto en la página HTML

Para this question necesitaba encontrar todos los nodos de texto debajo de un nodo en particular. Yo puedo hacerlo de esta manera:

function textNodesUnder(root){ 
    var textNodes = []; 
    addTextNodes(root); 
    [].forEach.call(root.querySelectorAll('*'),addTextNodes); 
    return textNodes; 

    function addTextNodes(el){ 
    textNodes = textNodes.concat(
     [].filter.call(el.childNodes,function(k){ 
     return k.nodeType==Node.TEXT_NODE; 
     }) 
    ); 
    } 
} 

Sin embargo, esto parece poco elegante a la luz del hecho de que con XPath uno podría simplemente preguntar para .//text() y hacerse con él.

¿Cuál es la forma más sencilla de obtener todos los nodos de texto bajo un elemento particular en un documento HTML, que funciona en IE9 +, Safari5 +, Chrome19 +, Firefox12 +, Opera11 +?

"Simplest" se define de forma general como "eficiente y corta, sin jugar al golf".

+1

http: // st ackoverflow.com/questions/2579666/getelementsbytagname-equivalent-for-textnodes –

+0

Aw, maldito. Gracias, Jack, busqué pero no pude encontrar esa pregunta. – Phrogz

+0

Sí, no sé por qué no apareció en la barra lateral tampoco, pero lo encontré mientras hacía una búsqueda en Google :) –

Respuesta

89

Sobre la base de la respuesta de @ Kennebec, una aplicación poco estricta de la misma lógica:

function textNodesUnder(node){ 
    var all = []; 
    for (node=node.firstChild;node;node=node.nextSibling){ 
    if (node.nodeType==3) all.push(node); 
    else all = all.concat(textNodesUnder(node)); 
    } 
    return all; 
} 

Sin embargo, mucho más rápido, con más fuerza, y más elegante es usar createTreeWalker para que el navegador filtra todo menos los nodos de texto para usted:

function textNodesUnder(el){ 
    var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false); 
    while(n=walk.nextNode()) a.push(n); 
    return a; 
} 
+3

@julmot En mi computadora, buscando todos los nodos de texto en esta página usando Chrome v50, toma 1900μs usando la primera técnica, pero 220μs usando la técnica TreeWalker. Entonces, 8 o 9 veces más rápido. – Phrogz

+1

Tuve que tweek esto para excluir el contenido de los elementos '

5
function deepText(node){ 
    var A= []; 
    if(node){ 
     node= node.firstChild; 
     while(node!= null){ 
      if(node.nodeType== 3) A[A.length]=node; 
      else A= A.concat(deepText(node)); 
      node= node.nextSibling; 
     } 
    } 
    return A; 
} 
+1

¿Qué tal 'while (node)' without the '! = Null'? – Phrogz

+2

O incluso 'for (node ​​= node.firstChild; node; node = node.nextSibling) {...}' – Phrogz

+1

Me preocupaba que la solución recursiva se topara con problemas de límite de pila, pero [ahora veo que esto es poco probable] (http://stackoverflow.com/questions/7826992/browser-javascript-stack-size-limit). – Phrogz

Cuestiones relacionadas