Actualización :
He descrito algunas pruebas de rendimiento básicas para cada uno de estos 6 métodos en 1000 ejecuciones. getElementsByTagNamees el más rápido, pero hace un trabajo a medias, ya que no selecciona todos los elementos, sino solo un tipo particular de etiqueta (creo p) y asume ciegamente que su firstChild es un elemento de texto. Puede que tenga algunos defectos, pero está ahí para fines de demostración y para comparar su rendimiento con TreeWalker. Ejecute las pruebas usted mismo en jsfiddle para ver los resultados.
- Usando un TreeWalker
- Recorrido iterativo personalizado
- Recorrido recursivo personalizado
- Consulta de XPath
- querySelectorAll
- getElementsByTagName
Supongamos por un momento que existe un método que le permite obtener todos los Textnodos de forma nativa. Aún tendría que atravesar cada nodo de texto resultante y llamar node.nodeValuepara obtener el texto real como lo haría con cualquier nodo DOM. Entonces, el problema del rendimiento no es iterar a través de los nodos de texto, sino a través de todos los nodos que no son texto y verificar su tipo. Yo diría (basado en los resultados) que TreeWalkerfunciona tan rápido como getElementsByTagName, si no más rápido (incluso con getElementsByTagName jugando con discapacidad).
Realicé cada prueba 1000 veces.
Método Total ms Promedio ms
--------------------------------------------------
document.TreeWalker 301 0.301
Recorrido iterativo 769 0,769
Traverser recursivo 7352 7.352
Consulta XPath 1849 1.849
querySelectorAll 1725 1.725
getElementsByTagName 212 0.212
Fuente para cada método:
TreeWalker
function nativeTreeWalker() {
var walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
var node;
var textNodes = [];
while(node = walker.nextNode()) {
textNodes.push(node.nodeValue);
}
}
Recorrido de árbol recursivo
function customRecursiveTreeWalker() {
var result = [];
(function findTextNodes(current) {
for(var i = 0; i < current.childNodes.length; i++) {
var child = current.childNodes[i];
if(child.nodeType == 3) {
result.push(child.nodeValue);
}
else {
findTextNodes(child);
}
}
})(document.body);
}
Recorrido iterativo del árbol
function customIterativeTreeWalker() {
var result = [];
var root = document.body;
var node = root.childNodes[0];
while(node != null) {
if(node.nodeType == 3) {
result.push(node.nodeValue);
}
if(node.hasChildNodes()) {
node = node.firstChild;
}
else {
while(node.nextSibling == null && node != root) {
node = node.parentNode;
}
node = node.nextSibling;
}
}
}
querySelectorAll
function nativeSelector() {
var elements = document.querySelectorAll("body, body *");
var results = [];
var child;
for(var i = 0; i < elements.length; i++) {
child = elements[i].childNodes[0];
if(elements[i].hasChildNodes() && child.nodeType == 3) {
results.push(child.nodeValue);
}
}
}
getElementsByTagName (desventaja)
function getElementsByTagName() {
var elements = document.getElementsByTagName("p");
var results = [];
for(var i = 0; i < elements.length; i++) {
results.push(elements[i].childNodes[0].nodeValue);
}
}
XPath
function xpathSelector() {
var xpathResult = document.evaluate(
"//*/text()",
document,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);
var results = [], res;
while(res = xpathResult.iterateNext()) {
results.push(res.nodeValue);
}
}
Además, puede encontrar útil esta discusión: http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node