2015-09-16 111 views
3

我目前正在學習遞歸,並試圖通過使用遞歸遍歷DOM來重新實現getElementsByClassName函數。我終於覺得自己已經掌握了這些概念,但當我將匹配元素推送到結果數組時,我遇到了問題。我的繼承人代碼:使用遞歸重新實現getElementsByClassName - Javascript

var getElementsByClassName = function(className){ 
    var results = []; 
    var domWalker = function(node) { 
    for (var i=0; i<node.children.length; i++) { 
     if (node.children[i].classList.contains(className)) { 
      console.log(node.children[i]) 
      results.push(node.children[i]) 
     } 

     if (node.children[i].children.length > 0) { 
      domWalker(node.children[i]) 
     } 

    } 
    return results; 
    }; 
    domWalker(document.body); 
    console.log(results) 
}; 

基本上,我需要的結果數組來保存它找到匹配的元素以HTML格式像這樣:

[<div class="title"></div>, <button class="click"></button>]

...然而,當我把這些元素融入我的結果數組更改爲:[div.title, button.click]格式。

我在調用results.push的上方添加了0​​語句,以查看在將結果推送到它們所在的數組之前結果是否以正確的格式顯示。被推送到數組的結果是我正在查找的結果,它們只是以錯誤的格式顯示。

爲什麼push會導致我的結果格式發生變化,我該如何解決這個問題?

+2

沒有格式更改,只有控制檯格式化數組,使更多的元素可視化地適合屏幕。數組項目本身就是你認爲他們是。如果你想要html源代碼,你可以得到最接近的是將'node.children [i] .outerHTML'推入你的數組而不是元素對象。 – dandavis

回答

0

node.children [I]保存到HTML元素的引用

的console.log()應用於一個隱式的ToString()方法給你看到的。

你需要這個額外的代碼(擴展到找到的所有可能的標記名):

var el = node.children[i]; 
el = '<' + el.tagName + (el.className ? ' class="' + el.className + '"': '') + '/>'; 
console.log(el); 
results.push(el); 
+0

爲什麼不使用'el.outerHTML'? – dandavis

+0

是的,當然,outerHTML適用於所有瀏覽器 – FoxInCloud

0

我曾幾何時解決了這個問題。雖然我沒有通讀你的解決方案,但我的評論很深。我希望它有幫助:

var getElementsByClassName = function(className, node){ 
    // The empty results array, which gets created whenever the function is 
    // called. 
    var results = []; 

    // Default the node to the document's body if it isn't set. This way, we can 
    // call the function recursively with child elements, but never have to 
    // worry about it the first time around. 
    node = node || document.body; 

    // If the node contains the class list in question, let's push it into the 
    // results array. 
    if (node.classList && node.classList.contains(className)) { 
    results.push(node); 
    } 

    // Now, let's fetch the child nodes of the current node. 
    var children = node.childNodes; 

    // If child nodes exist, then we proceed here. 
    if (children) { 
    // Let's now loop over all child nodes of the current node in question. This 
    // way, we'll be able to perform checks on each child node. 
    for (var i = 0; i < children.length; i++) { 
     // Fetch the i child node. 
     var child = children[i]; 

     // At this point, we want to pass the child node back into the function, 
     // implementing recursion. The same checks above will occur, and if the 
     // node has the class name, it will be added to the results array from 
     // that function call. 
     // 
     // This returns an array, and we need to merge it with the current set 
     // of results, so we concat it. 
     // 
     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat 
     results = results.concat(getElementsByClassName(className, child)); 
    } 
    } 

    // We then return the combined results array from all the recursive function 
    // calls! 
    return results; 
};