2015-06-27 20 views
1

爲了更加熟悉遞歸DOM &,我決定從頭開始重新創建getElementsByClassName(僅適用於vanilla JS,不適用於jQuery)。目前,我可以在DOM中找到所有具有我想要的類的元素,但是遇到了只能獲得具有兩個特定類(或更多)的元素的方法的問題。從零開始重新實現getElementsByClassName(僅限於Vanilla JS)

<div class="one two"> 
    <h1 class="one"> 
     <span class="one two"> 
    </h1> 
</div> 

我當前實現返回我的期望,返回包含類 '一' 的每一個元素:

我試圖去:

getElementsByClassName('one two'); 
[<div class="one two"></div>, <span class="one two"</span>] 

我遇到的問題之一是classList.contains:

element.classList; 
// ['one, 'two']; 

element.classList.contain("one"); 
//returns true since the value actually exists 


//PROBLEM: 
element.classList.contains("one two"); 
//this is looking for "one two" in the array and not 'one' and 'two'. 
//this returns false & my code breaks 

//How would I be able to do something like this, even if it 
//means recreating my own helper contains function? 
contains('one','two'); 

我的功能:

var getElementsByClassName = function(className){ 
    var results = []; 
    function getClass(nodeList){ 
    var childList = nodeList.children; 
    _forEach(childList, function(node) { 
    //1st level body check 
     if(node.classList && node.classList.contains(className)){ 
     results.push(node); 
     } 

     //has children, recurse 
     if(node.children) { 
     getClass(node); 
     } 
     else { 
     getClass(node); 
     } 
    }); 
    } 
    getClass(document.body); 
    return results; 
} 



//Helper forEach function to iterate over array like DOM objects 
var _forEach = function(collection, func) { 
for(var i = 0; i < collection.length; i++) { 
    func(collection[i], i, collection); 
} 
} 
+1

'[ '一',「二'] .every(function(className){return node.classList.contains(className); })' –

+1

謝謝,幾個星期前我剛開始學習幾個月的編程和函數式編程。時間解剖這=)。 –

+0

你很好,你有關鍵要素:真正努力學習。好一個。 (這就是爲什麼我沒有這樣做的原因,只是指出*你會怎麼做。) –

回答

2

評論中的代碼  —我還沒有實現它適合你,只是指出,你會怎麼做:

var getElementsByClassName = function(className){ 
    // ***Here, split className on whitespace into an array ** 
    var results = []; 
    function getClass(nodeList){ 
    var childList = nodeList.children; 
    _forEach(childList, function(node) { 
    //1st level body check 
     // **Here, only include the element if Array#every is true, 
     // **where you give Array#every a function that does your 
     // classList.contains on the name for that iteration 
     if(node.classList && node.classList.contains(className)){ 
     results.push(node); 
     } 

     //has children, recurse 
     if(node.children) { 
     getClass(node); 
     } 
     else { 
     getClass(node); 
     } 
    }); 
    } 
    getClass(document.body); 
    return results; 
}