Cập nhật:
tôi đã vạch ra một số xét nghiệm hiệu suất cơ bản đối với mỗi một trong các phương pháp 6 trên 1000 chạy. getElementsByTagName
là nhanh nhất nhưng nó thực hiện một nửa công việc, vì nó không chọn tất cả các yếu tố, nhưng chỉ có một loại thẻ cụ thể (tôi nghĩ p
) và mù quáng giả định rằng firstChild của nó là một phần tử văn bản. Nó có thể hơi thiếu sót nhưng ở đó cho mục đích trình diễn và so sánh hiệu suất của nó với TreeWalker
. Run the tests yourselves on jsfiddle để xem kết quả.
- Sử dụng một TreeWalker
- Tuỳ chỉnh lặp Traversal
- Tuỳ chỉnh Recursive Traversal
- XPath truy vấn
- querySelectorAll
- getElementsByTagName
Giả sử trong chốc lát rằng có một phương pháp cho phép bạn nhận tất cả Text
nút nguyên bản. Bạn vẫn sẽ phải đi qua từng nút văn bản kết quả và gọi node.nodeValue
để nhận được văn bản thực tế giống như bạn thực hiện với bất kỳ Nút DOM nào. Vì vậy, vấn đề hiệu suất không phải là với việc lặp qua các nút văn bản, nhưng lặp qua tất cả các nút không phải là văn bản và kiểm tra loại của chúng. Tôi sẽ tranh luận (dựa trên kết quả) rằng TreeWalker
hoạt động nhanh như getElementsByTagName
, nếu không nhanh hơn (ngay cả với getElementsByTagName đang chơi khuyết tật).
Ran each test 1000 times.
Method Total ms Average ms
--------------------------------------------------
document.TreeWalker 301 0.301
Iterative Traverser 769 0.769
Recursive Traverser 7352 7.352
XPath query 1849 1.849
querySelectorAll 1725 1.725
getElementsByTagName 212 0.212
Nguồn cho từng phương pháp:
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);
}
}
Recursive Tree Traversal
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);
}
lặp Tree Traversal
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 (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); /* Fixed a bug here. Thanks @theazureshadow */
}
}
Ngoài ra, bạn có thể tìm thấy thảo luận này có hữu ích - http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node
Thú vị .. Có 'createTreeWalker()' làm việc trên IE không? – levik
Tôi đã nhận được kết quả hỗn hợp cho từng phương pháp ở trên trong trình duyệt khác nhau - những kết quả này ở trên dành cho Chrome. Firefox và Safari hoạt động rất khác nhau. Tôi không có quyền truy cập vào IE không may, nhưng bạn có thể kiểm tra các bản thân trên IE để xem nó có hoạt động hay không. Đối với tối ưu hóa trình duyệt, tôi sẽ không lo lắng về việc chọn một phương pháp khác nhau cho mỗi trình duyệt miễn là sự khác biệt là theo thứ tự của hàng chục mili giây hoặc thậm chí là hàng trăm thấp. – Anurag
Đây là một câu trả lời thực sự hữu ích, nhưng hãy cẩn thận rằng các phương pháp khác nhau trả về những điều rất khác nhau. Nhiều người trong số họ chỉ nhận được các nút văn bản nếu họ là con đầu tiên của cha mẹ của họ. Một số người trong số họ chỉ có thể nhận được văn bản, trong khi những người khác có thể trả lại các nút văn bản thực tế với những sửa đổi nhỏ. Có lỗi trong Chuyển đổi cây lặp đi lặp lại có thể ảnh hưởng đến hiệu suất của nó. Thay đổi 'node.nodeType = 3' thành' node.nodeType == 3' – theazureshadow