2011-08-06 93 views
1

這是Crockford的JavaScript代碼:The Good Parts。遞歸下載DOM樹

var results = []; 

var walkDOM = function (node,func) { 
     func(node);      //What does this do? 
     node = node.firstChild; 
     while(node) { 
      walkDOM(node,func); 
      node = node.nextSibling; 
     } 

    }; 

我瞭解代碼,但func(node)除外。我想重點是通過node作爲函數func中的參數,但瀏覽器如何以這種方式理解它? nodefunc可以是任何東西 - 所以,當函數被調用它可以這樣寫:

​​3210

func傳遞,walkDOM將處理功能(ATT){...}(document.body的) - - 這沒有任何意義。那麼爲什麼Crockford選擇包含func(節點)?

+2

預期使用'顯影劑walkDOM'將它傳遞*預計*的函數接收DOM被稱爲參數。你的函數預計會收到一個屬性名稱,因此不合適。 – user113716

+0

@ patrick_dw - 我還是不明白'func(node)'的符號。開發者是否應該用'function(node)'替換它?如果不是,'func(node)'對瀏覽器有意義嗎? – dopatraman

+0

瀏覽器不需要理解它。只有編寫傳遞給'walkDOM'的函數的開發人員需要理解它。如果我想走DOM,將每個*文本節點*作爲目標,並用*「patrick dw很好看」替換它的文本*,那麼我會將該邏輯放在我傳遞的函數中。 'walkDOM'將每個節點傳遞給* your *函數(一次一個),*你的*函數負責對該節點做些什麼。 – user113716

回答

5

在我看來,func用於對樹中的每個節點做某事。

例如,如果我想在整個樹的每個節點警示標籤名稱:

walkDOM(document.body, function(node) { 
    alert(node.tagName); 
}); 

在你的榜樣作用:

walkDOM(document.body,function(att) { 
     node.getAttribute(att); 
     results.push(node); 
     }); 

...你有一個名爲node參數設置爲att,但這不會在屬性的名稱中奇蹟般地產生。我期望當「node.getAttribute(att)」運行時,因爲節點被設置爲att ......在該函數的範圍內沒有node,所以「變量」節點未定義「。

7

是的,這樹的遍歷功能有道理的,因爲:

  • 函數的參數應該知道如何處理(任何)節點
  • 第一個呼叫參數應該是一個支持節點(不是文檔例如,如果func不知道如何處理它)

這就是說,這個算法仍然看起來不正確,因爲它只通過第一個兄弟來探索;其他兄弟姐妹將被簡單地忽略。因此,我建議使用這種更傳統的方法來代替:

function walk(node, func) { 
    var children = node.childNodes; 
    for (var i = 0; i < children.length; i++) // Children are siblings to each other 
     walk(children[i], func); 
    func(node); 
} 

注意,版本是「深第一」(即不調用呼叫處理孩子之前FUNC()),但我寧願推薦它,因爲FUNC可能改變節點。通過這種方式,父母的處理將能夠在發佈可能不適當的更改之前考慮其已處理孩子的最新狀態。

3

func這是在

func(node) 

線就是通常被稱爲回調函數。它是可用於walkDOM功能的功能。它可能是有意義有一個更詳細的功能名稱:

var results = []; 

var walkDOM = function (node, iCanBeCalledOnANode) { 
    iCanBeCalledOnANode(node); // Will be called on every DOM element 
    node = node.firstChild; 
    while(node) { 
     walkDOM(node,func); 
     node = node.nextSibling; 
    } 

}; 

希望這將清除的東西了你。

0

Crockford的代碼將一個回調傳遞給walkDOM,它可以用很多方式處理傳遞給它的參數。

一個例子可以是返回與指定的標記所有DOM元素的計數的方法:

var getTagNameCount = function(tagName) { 
    var count = 0; 
    walkDOM(document.body, function(node) { 
     if (node.tagName === tagName) { 
      count++; 
     } 
    }); 
    return count; 
};