# jQuery selector function in JavaScript

I've reproduced the jQuery selector function in JavaScript.

Here are the two rules that come with this function:

1. You may not use any JavaScript libraries.
2. document.querySelector/document.querySelectorAll may not be used.

var $= function (selector) { var elements = []; // get starting index position of id / class var classPosition = selector.split('').indexOf("."); var idPosition = selector.split('').indexOf("#"); // split selector into array var selectorArray = selector.split(""); if ( classPosition === -1 && idPosition === -1){ // simply set equal elements to DOM object with the specific tag name elements = document.getElementsByTagName(selector); }else if (classPosition > -1 && idPosition === -1 ){ if (classPosition === 0) { selectorArray.shift(); // array elements returns DOM object with the desired class name elements = document.getElementsByClassName(selectorArray.join("")); }else { // array elements returns DOM object with the matching class var tagElem = selectorArray.slice(0,classPosition).join(""); var className = selectorArray.slice(classPosition + 1,selectorArray.length).join(""); var tagElemCollection = document.getElementsByTagName(tagElem); // iterate through DOM object check if class match match className for (var i = 0; i < tagElemCollection.length; i++) { if (tagElemCollection[i].className != "") { var eachClass = tagElemCollection[i].className.split(" "); for (var e = 0;e < eachClass.length;e++) { if (eachClass[e] === className ) { elements.push(tagElemCollection[i]); } } } } } }else if ( idPosition > -1 && classPosition === -1){ if (idPosition === 0) { // array elements returns DOM object if an id is passed in selectorArray.shift(); elements.push(document.getElementById(selectorArray.join(""))); }else { var tagElem = selectorArray.slice(0,idPosition).join(""); var idName = selectorArray.slice(idPosition + 1,selectorArray.length).join(""); var tagElemCollection = document.getElementsByTagName(tagElem); // iterate through DOM object check if id match match idName (same logic as before) for (var i = 0; i < tagElemCollection.length; i++) { if (tagElemCollection[i].id != "") { var eachId = tagElemCollection[i].id.split(" "); for (var e = 0;e < eachId.length;e++) { if (eachId[e] === idName ) { elements.push(tagElemCollection[i]); } } } } } }else if (idPosition > -1 && classPosition > -1){ // check if position of id is before position of class if (idPosition < classPosition) { var selectorIdTag = selectorArray.slice(idPosition,classPosition); selectorIdTag.shift(); // push in elements the DOM object with id specified elements.push(document.getElementById(selectorIdTag.join(""))); }else{ // if class is before id loop through DOM object with that class and select // only the one that has also the id specified. var selectorClassTag = selectorArray.slice(classPosition,idPosition); var selectorIdTag = selectorArray.slice(idPosition, selectorArray.length); selectorClassTag.shift(); selectorIdTag.shift(); var ClassMatch = document.getElementsByClassName(selectorClassTag.join("")); for (var p=0; p < ClassMatch.length; p++){ if (ClassMatch[p].id === selectorIdTag.join("") ){ elements.push(ClassMatch[p]); } } } } return elements; }  Here, the function $ takes an argument selector which is a string representing the desired DOM element.

Example

Let's say I have an HTML page that looks like this:

<html>
<body onload="test$()"> <div></div> <div id="some_id" class="some_class some_other_class"></div> <img id="some_other_id" class="some_class some_other_class"></img> <input type="text"> </body> </html>  Using the function $ just created, select the element div of class some_other_class:

\$('div.some_other_class')


returns an array containing the desired element(s):

 [<div id=​"some_id" class=​"some_class some_other_class">​</div>​]


I'd like to know about the quality and performance of my code. I do feel like I'm doing too many iterations.

First off, you have a bug. On the line if (tagElemCollection[i].id != "") {, you used the != operator instead of the !== operator. This line should be changed to if (tagElemCollection[i].id !== "") {.
Secondly, you have some spacing inconsistencies. For example, you wrote }else { in some places, and }else{ in others, when it should be } else {, and/or } else if {. You also have stuff like this, (var e = 0;e < eachId.length;e++), or this (var p=0; p < ClassMatch.length; p++), that can both be typed like this: (var name = ...; name ... value; name...). Try to find inconsistencies like these and change them.
Finally, you have some indentation issues. The general style is that lines should be indented by one tab, or four spaces if they're in a if/else if/else/function/etc block.