JavaScript

Organizing your JavaScript

Relative to other languages, learning JavaScript is a much easier process. It's easy to use it to add a functionality to your website. For example making a pop up appear after a click is only a few lines of code. You can add things like code highlighting too with only a few more lines. But saying everything in JavaScript is easy is not true.

If I ask you to add a pop up box on a big website that already has lots of code and lots of users, your confidence will not be at the same level. The problem here is the way the code is organized.

So today, let's see how you can organize your code to make it easier to update and maintain.

There are many ways to organize your code in JavaScript. For example, here is how I can display an alert box when you click on a button.

inline

<button onclick="alert('I pop up therefor I am');">I make Alert Boxes</button>

Script Tag

<button id="box-maker">Box Maker</button>
<script>
document.getElementById("box-maker").onclick = function(){
    alert("Am I a box, or a man thinking of a box?");
};
</script>

In the Head or external file

<head>
<script>
window.onload = function() {
    document.getElementById("box-maker").onclick = function(){
        alert("Look at me, I'm so complicated");
    };
}
</script>
</head>
<body>
    <button id="box-maker">Box Maker</button>
</body>

Each method has its advantages but I favor a mixture of external and script tag. By using an external file, you separate the presentation part of your code from the logic. It's very easy to create chaos if all your code is mixed with the HTML. For example, with in-line code, if you want to update what the alert box says, you have to hunt it down inside your HTML. With an external file you can have this text in a simple variable that can be easily updated.

The best way to organize your code.

I separate my code into 2 files:

Library

The library is generic. There I add all my time savers functions: DOM selectors, Ajax callers, Array modifiers, String Modifiers, Event handling or anything that is not specific to my website.

Array.prototype.loop = function (fn){
    var l = this.length;
    for (var i=0;i<l;i++){
        var item = this[i];
        fn.apply(item,[i]);
    }
};
...
addEvent = function (obj, evType, fn) {
    if (!obj){
        this.error("You assigned a function to a null. Simply.addEvent() requires a DOM object\nEventType:"+evType+"\nfunction:"+fn);
        return false;
    }
    var newFn = addEvent == "attachEvent"? function (e){var evt = e || window.event;if(!evt.preventDefault)evt.preventDefault = function() {this.returnValue = false;};return fn.apply(obj,[evt]);}: fn;

    this.evtFunctions.push([funcId,newFn,evType]);

    obj._funcEvt = obj._funcEvt?obj._funcEvt:[];
    obj._funcEvt.push([funcId,evType]);
    funcId++;
    return obj == window &amp;&amp; evType == "load" &amp;&amp; onloadFired ?newFn(): obj[addEvent](on+evType,newFn,false);
};
...

Functionality

This is where I add a widget functionality. If I want to add an option for user to register to my newsletter I add it right here. Note that it is very easy to get this file cluttered. So what I usually do is separate it into sections, like a controller. This can be further divided into multiple files, just so you don't have all the website functionality into a single file.

Here is an example:

(function () {
    var controller = {

    newsletterWidget: function () {
        // Here you can add all Newsletter widgets code
    },

    codeHighlightWidget: function (className) {
        // Code for CodeHighlighting goes here
    },

    DestroyerWidget : function (IEVersion) {
        if (IEVersion < 9) {
            Destroyer.destroy(Browser.self).destroy(Browser.OS.harddrive).hurt(User.Feelings);
        }
    }

    };

    MainController.add(controller);

})();

This method spares you from writing spaghetti code everywhere.

On the HTML part, it is good practice to have good identifiers on your tags to know that an element will be manipulated by JavaScript. For example, I prepend all my JS interacting tags with a js-.

<div class="newsletter js-newsletterWidget" >
    Hey! Give me your email!
</div>

Adding scripts to the page

Personally, I have two ways to add my code. It mostly depends on the kind of project I are working on. There are times where I have to use Synchronous codes, and others Asynchronous.

Synchronous

When code has to be loaded in order, the best way is to load all your code at the end of your document.

<body>
....

<script src="path/jQuery.js" type="text/javascript"></script>
<script src="path/myfunctions.js" type="text/javascript"></script>
<script src="path/mycode.js" type="text/javascript"></script>
</body>
</html>

This makes the main content of your website load first so your users can get started without having to wait for your page to finish downloading. This works most cases. But if you are working on a website where you don't have the luxury of "synchronousity" we have a solution.

Asynchronous

In this case, the order of your scripts being loaded is not guarantied. It depends on the users computer speed and internet connection. However, there are advantages. You can load multiple scripts in parallel.

<script>
(function(list){
var i = 0,l = list.length, s = document.scripts[0] || document.getElementsByTagName("script")[0],
a = null;
for (;i<l;i++){
    a = document.createElement("script");
    a.type = "text/javascript";
    a.async = true;
    a.src = list[i];
    s.parentNode.insertBefore(a, s);
}
})(["jQuery.js","myfunctions.js","mycode.js"]);
</script>

What this script does is append a list of scripts asynchronously to the head of the document. This topic is a little more advance, because it requires you to write async functions that can be called later when they are defined. I wrote about it in the past so feel free to check if you want to learn more about async JavaScript.

No matter which method you use, the goal is to be able to comeback in the future and still be able to modify and update your code with minimum overhead. Separating your code in small chunks is always best. Plus we can always use a dynamic language to combine all the files before serving them on our website.

Happy Coding

Originally Posted on Feb 6, 2015 @ 1:37


Comments

There are no comments added yet.

Let's hear your thoughts

For my eyes only