2012-05-24 15 views
28

Mögliche Duplizieren:
getElementsByTagName() equivalent for textNodesSuche alle Textknoten in HTML-Seite

Für this question I benötigt, um alle Textknoten unter einem bestimmten Knoten zu finden. Ich kann tut dies etwa so:

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; 
     }) 
    ); 
    } 
} 

Dies scheint jedoch unelegant in Anbetracht der Tatsache, dass mit XPath man einfach für .//text() nicht abfragen und mit ihr geschehen.

Was ist der einfachste Weg, um alle Textknoten unter einem bestimmten Element in einem HTML-Dokument, das auf IE9 +, Safari5 +, Chrome19 +, Firefox12 +, Opera11 + funktioniert?

"Einfachste" ist definiert als "effizient und kurz, ohne Golf".

+1

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

+0

Aw, bugger. Danke, Jack, ich habe gesucht, aber diese Frage nicht gefunden. – Phrogz

+0

Ja, ich weiß nicht, warum es auch nicht in der Seitenleiste auftauchte, aber ich fand es bei einer Google-Suche :) –

Antwort

89

Basierend auf Antwort des @ kennebec, eine etwas straffere Umsetzung der gleichen Logik:

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; 
} 

jedoch weit schneller, straffer und eleganter wird mit createTreeWalker so dass der Browser Filtert alles außer den Textknoten für Sie aus:

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 Auf meinem Computer, der mit Chrome v50 nach allen Textknoten auf dieser Seite sucht, benötigt man 1900μs mit der ersten Technik, aber 220μs mit der TreeWalker-Technik. Also, 8 oder 9 mal schneller. – Phrogz

+1

Ich musste dies tweek, um den Inhalt von '

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

Wie wäre es mit while (Knoten) 'ohne das'! = Null'? – Phrogz

+2

Oder sogar 'für (node ​​= node.firstChild; node; node = node.nextSibling) {...}' – Phrogz

+1

Ich habe mir Sorgen gemacht, dass die rekursive Lösung Probleme mit dem Stack-Limit verursachen könnte, aber [ich sehe jetzt, dass dies unwahrscheinlich ist] (http://stackoverflow.com/questions/7826992/browser-javascript-stack-size-limit). – Phrogz