Update :
Ich habe einige grundlegende Leistungstests für jede dieser 6 Methoden über 1000 Läufe skizziert. getElementsByTagName
ist das schnellste, aber es macht einen halbherzigen Job, da es nicht alle Elemente auswählt, sondern nur einen bestimmten Tag-Typ (glaube ich p
) und blind davon ausgeht, dass sein erstes Kind ein Textelement ist. Es mag wenig fehlerhaft sein, aber es dient zu Demonstrationszwecken und zum Vergleich seiner Leistung mit TreeWalker
. Führen Sie die Tests selbst auf jsfiddle durch , um die Ergebnisse zu sehen.
- Verwenden eines TreeWalker
- Benutzerdefinierte iterative Durchquerung
- Benutzerdefinierte rekursive Durchquerung
- Xpath-Abfrage
- querySelectorAll
- getElementsByTagName
Nehmen wir für einen Moment an, dass es eine Methode gibt, mit der Sie alle Text
Knoten nativ abrufen können. Sie müssten immer noch jeden resultierenden Textknoten durchlaufen und aufrufen node.nodeValue
, um den tatsächlichen Text zu erhalten, wie Sie es mit jedem DOM-Knoten tun würden. Das Problem der Leistung besteht also nicht darin, Textknoten zu durchlaufen, sondern alle Knoten, die kein Text sind, zu durchlaufen und ihren Typ zu überprüfen. Ich würde argumentieren (basierend auf den Ergebnissen), dass TreeWalker
die Leistung genauso schnell ist getElementsByTagName
, wenn nicht sogar schneller (selbst wenn getElementsByTagName behindert spielt).
Lief jeden Test 1000 Mal.
Methode Gesamt ms Durchschnitt ms
--------------------------------------------------
document.TreeWalker 301 0.301
Iterativer Traverser 769 0,769
Rekursiver Traverser 7352 7.352
XPath-Abfrage 1849 1.849
querySelectorAll 1725 1.725
getElementsByTagName 212 0.212
Quelle für jede Methode:
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);
}
}
Rekursive Baumdurchquerung
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);
}
Iterative Baumdurchquerung
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 (Handicap)
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);
}
}
Diese Diskussion ist möglicherweise auch hilfreich - http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node