更新:
1000回の実行でこれら6つのメソッドのそれぞれについていくつかの基本的なパフォーマンステストの概要を説明しました。getElementsByTagName
は最速ですが、すべての要素を選択するわけではなく、特定の種類のタグ(私は思うp
)を1つだけ選択し、そのfirstChildがテキスト要素であると盲目的に想定するため、中途半端な仕事をします。少し欠陥があるかもしれませんが、デモンストレーションの目的で、パフォーマンスをと比較するためにありTreeWalker
ます。jsfiddleで自分でテストを実行して、結果を確認します。
- TreeWalkerの使用
- カスタム反復トラバーサル
- カスタム再帰トラバーサル
- Xpathクエリ
- querySelectorAll
- getElementsByTagName
Text
少しの間、すべてのノードをネイティブに取得できるメソッドがあると仮定しましょう。他のDOMノードの場合と同じように、結果の各テキストノードをトラバースし、呼び出しnode.nodeValue
て実際のテキストを取得する必要があります。したがって、パフォーマンスの問題は、テキストノードを反復処理することではなく、テキストではないすべてのノードを反復処理してそれらのタイプをチェックすることです。私は(結果に基づいて)それが(getElementsByTagNameが障害者である場合でも)速くはないにしても、TreeWalker
同じくらい速く実行されると主張します。getElementsByTagName
各テストを1000回実行しました。
メソッド合計ミリ秒平均ミリ秒
--------------------------------------------------
document.TreeWalker 301 0.301
反復トラバーサー7690.769
再帰的トラバーサー73527.352
XPathクエリ18491.849
querySelectorAll 1725 1.725
getElementsByTagName 212 0.212
各メソッドのソース:
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);
}
}
再帰的なツリートラバーサル
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);
}
反復ツリートラバーサル
function customIterativeTreeWalker() {
var result = [];
var root = document.body;
var node = root.childNodes[0];
while(node != null) {
if(node.nodeType == 3) { /* Fixed a bug here. Thanks @theazureshadow */
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 *"); /* Fixed a bug here. Thanks @theazureshadow */
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(ハンディキャップ)
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); /* Fixed a bug here. Thanks @theazureshadow */
}
}
また、このディスカッションが役立つ場合があります-http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node