<getElementsByClassName by Walking down the DOM ⁄ >

In JavaScript we have a few methods to get html objects, such as getElementById, getElementsByName, getElementsByTagName, normally these methods will be enough, but what if want to get all elements but by their class name? Well, easy, we build one.

All modern javascript framework have that already built-in, in jQuery is just as easy as $(".mClass"), in this snippet I'll try to show a possible manner to get all elements by their class name, getElementsByClassName.

So we'll examine all the DOM (in this example under document.body), and check all objects class name, if it matches our search than we'll add it to an array.
After retrieving that array we can do whatever we want to it, to give a few examples I also built a few DOM methods.

BasicDom.js, this class will allow us to make some simple changes in DOM, it receives an array with the elements that we want to modify. For example we can Capitalize and Reverse strings, apply Css styles, set inner html in allowed elements.

/**

* This class will allow us to make some simple operations

* in a given Dom Tree

*

* @author: pedrocorreia.net

*/

var BasicDom = function(dom){

//cache DOM

var _dom = dom;

/**

* Check if we have a valid Dom tree

*

* @return Bool

*/

var _isDomTreeValid = (function(){

for(var el in _dom){

if(el && !_dom[el].tagName){

return;

}

}

returntrue;

})();

//check if our dom tree's valid

if(!_isDomTreeValid){throw"DomTree empty or nor valid"; }

/**

* Set CSS attributes

*

* @param Object Properties key=>value

* @return this

*/

var _css = function(prop){

var _styles = [];

for(var p in prop){

if(p){ _styles.push(p + ":" + prop[p] + ";"); }

}

var style = _styles.join(" ");

for(var el in _dom){

if(el){

try{_dom[el].style.cssText = style;}

catch(ex){}

}

}

returnthis;

};

/**

* Set object inner html value

*

* @param Object

* @param String Value

* @return this

*/

var _innerHtml = function(o, v){

var _invalid = ["COL", "COLGROUP", "FRAMESET", "HTML", "STYLE",

"TABLE", "TBODY", "TFOOT", "THEAD", "TITLE", "TR"].join();

if(_invalid.indexOf(o.tagName) < 0){

try{ o.innerHTML = v; }

catch(ex){}

}

};

/**

* Set html content

*

* @param String Text

* @return this

*/

var _html = function(txt){

for(var el in _dom){

if(el){ _innerHtml(_dom[el], txt); }

}

returnthis;

};

/**

* Reverse String

*

* @return this

*/

var _reverse = function(){

for(var el in _dom){

if(el){

_innerHtml(_dom[el], _dom[el].innerHTML

.split("")

.reverse()

.join("")

);

}

}

returnthis;

};

/**

* Capitalize Words

*

* @return this

*/

var _capitalize = function(){

var arr = [];

for(var el in _dom){

if(el){

arr = _dom[el].innerHTML.toLowerCase().split(" ");

for(var i = 0, count = arr.length; i < count; i++){

arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);

}

_innerHtml(_dom[el], arr.join(" "));

}

}

returnthis;

};

/**

* @return Function Css

* @return Function Html

* @return Function Reverse

* @return Function Capitalize

* @return Boolean Is Dom Tree Valid?

* @return Object Dom tree

**/

return{

Css: _css,

Html: _html,

Reverse: _reverse,

Capitalize: _capitalize,

IsValid: _isDomTreeValid,

Dom: _dom

};

};

getElementsByClassName, this is our main class. I used a recursive approach by walking down the DOM, we have many ways to get, other one was to use document.getElementsByTagName("*");

/**

* Filter html elements by its correspondent class name

* This will follow a recursive approach

*

* @return Object Dom Tree

*/

var getElementsByClassName = function(cls){

//elements array

var _elems = [];

/**

* Walking down Dom Tree

* Recursive Approach

*

* @param Object Node

*/

(function(start_node){

if(!start_node){ start_node = document.body; }

var node = "";

for(var i = 0, count = start_node.childNodes.length; i < count; i++){

node = start_node.childNodes[i];

if(node.hasChildNodes()){

arguments.callee(node); //recursive call

}

if(node.className && node.className.indexOf(cls) >= 0){

_elems.push(node);

}

}

})();

return _elems;

};

Init.js, our startup script. In here we'll have two different ways to use getElementsByClassName, by using BasicDom class or just iterate over the array returned by getElementsByClassName, each one's a valid way and has the same purposes.