3
\$\begingroup\$

I'm working on my framework constructor. First I tried to look into jQuery and understand it, but it's so out of my league. Instead I googled and put this code together. Though there aren't many posts about creating a framework. Anyway, since I'm not a guru I might be doing it the wrong way or missing things. Can I take your opinions, suggestions to make it a little more stable?

FIDDLE

var optionalSelector = "$";

(function () {
    (this[arguments[0]] = function constructor(input) {
        if (!(this instanceof constructor)) {
            return new constructor(input);
        }

        var regExp_id = /^#/;
        var regExp_class = /^\./;
        var regExp_tag = /[^#]|[^.]/;

        var typeOfInput;

        function isElement(obj) {
            if (obj !== null && typeof obj === "object") {
                return obj;
            }
        }

        if (isElement(input)) {
            return input;
        } // this
        else {
            if (input.search(regExp_id) != -1) {
                typeOfInput = "id";
            } else if (input.search(regExp_class) != -1) {
                typeOfInput = "class";
            } else if (input.search(regExp_tag) != -1) {
                typeOfInput = "tag";
            }

            switch (typeOfInput) {

                case "id":
                    if (document.getElementById(input.replace(/#/, ""))) {
                        return document.getElementById(input.replace(/#/, ""));
                    } else {
                        console.log("Invalid id: " + input);
                        return false;
                    }
                    break;

                case "class":
                    if (document.getElementsByClassName(input.replace(/./, "")).length > 0) {
                        return document.getElementsByClassName(input.replace(/./, ""));
                    } else {
                        console.log("Invalid class: " + input);
                        return false;
                    }
                    break;

                case "tag":
                    if (document.getElementsByTagName(input).length > 0) {
                        return document.getElementsByTagName(input);
                    } else {
                        console.log("Invalid tag: " + input);
                        return false;
                    }
                    break;
            }
        }
    })
})(optionalSelector);
\$\endgroup\$
4
\$\begingroup\$

First of all, nice effort for the code. But I highly go against it because there's jQuery. And if you don't like jQuery because it's heavy, then I suggest going for Sizzle.

But anyways, back to your code. First I notice this one:

var optionalSelector = "$";

Never use $. It's being abused already by frameworks. Use another namespace to avoid collisions with mainstream libraries, something unique, like MyVeryAmazingDomLibrary or MVADL for short. Hehehe.

Also, I notice this namespace declaration happens to be outside the library. Do include it inside the library's module:

;(function(window){
  ...
  window.myNamespace = myLibraryStuffHere;
  ...
}(window));

So far, your code looks ok. Everything is pretty much covered. I also see that it works only with single selectors at the moment. However, I notice you are using replace to remove the # and .:

document.getElementById(input.replace(/#/, ""));

RegExp is heavy for trivial operations such as this. You can remove the first character using substr or substring. That way, you avoid RegExp.

document.getElementById(input.substr(1));

Now, in the demo, I see this:

a[0].onclick = function() { alert("you clicked the classes"); }
a[1].onclick = function() { alert("you clicked the classes"); }

If you had a hundred elements, would you do this still? I assume you'd do a loop, right? But wouldn't it be neat if the library took care of that? Yes?

So there's a reason they call it a "jQuery object". jQuery objects are basically arrays (array-like to be exact, normally called a set or collection) that applies operations to each item in the collection.

So to get you on the right track, think of this code:

a.on('click',someFunction);

a is the jQuery object, and on is a method of jQuery that attaches a click handler to each item in set a. on would look like:

myAmazingLibraryObject.prototype.on = function(event,handler){

  //assuming "this" represents the current collection and "elements"
  //is an array of elements, a result of getting by tag or by class.
  //Let's say we are standards compliant and ES5 compliant, 
  //we use forEach to loop through the set, and addEventListener to 
  //add the handlers.

  this.elements.forEach(function(element){
    element.addEventListener(event,handler,false);
  });
}

Now, you can do this:

var elements = myAmazingLibrary('a'); //get all <a>

elements.on('click',function(event){
  event.preventDefault();
  console.log('clicked');
});

An advantage of using a jQuery-like object, where the results are contained in an array, is that even when your collection is empty, the code does not break. If we used on on an empty collection, nothing will go wrong. Empty set, no loop, no element access, no error.

Lastly, don't just console.log or return false on errors. Throw meaningful errors instead. Use Error objects so that try-catch can collect them and inspect them. The last thing you would want from your code is to have it running broken and not know about it.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks for the suggestions. I'm not coding for living, but for fun. That's why I try to avoid using libraries. With libraries work gets done but you don't know what's going on. I wanted to create my own framework to practise and get a better understanding. Last state of the code. Also will add the try-catch method. Oh, and about handling arrays. Of course I'd use a loop. I have methods for these :) \$\endgroup\$ – akinuri Dec 2 '13 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.