Create Javascript Library From Scratch

Almost every web developer has encountered use of jQuery in daily life coding. This post is about how to create javascript library from scratch like jQuery.

Write a Javascript Library From Scratch

As a developer you must be familiar with the most popular javascript library jQuery. There are plenty of other libraries extending the functionality of jQuery and they require jQuery to be included in order to serve their purpose and functionality. This post will show you how to create javascript library of your own. We will create a JS library replicating a few features of jQuery as an example. We will be using IIFE (immediately invoked function expression) approach to initialize our library.

It is going to be a simple library just to illustrate basic working model of jQuery. First we are going to create a js object and we are going to use $$ as object name. We will be using Immediately Invoked Function Expression to create the instance of our library object. Let's start with defining our object using self-invoking function which accepts a selector as a parameter.

 

Create Javascript Library Definition with Self-Invoking Function

So what have we achieved so far now? We can select elements like jQuery using $$("p"), $$(window), $$(document) etc. A brief step by step explanation of code above is:

  • Call self invoking function with provided parameters window and document object.
  • Check if the $$ is called as a constructor, If not then create a new instance of $$.
  • Setup the this and elements array for storing selected elements.
  • Define various types of selectors including HTML element and a selector as string.
  • Select all elements and append them to elements array.
  • Append the $$ object to window object.
(function (win, doc) {
    function $$(selector) {
        // Initiate the object if it hasn't been initiated
        if (!(this instanceof $$)) {
            return new $$(selector);
        }

        this.length = 0;
        var elements = [];
if(selector instanceof HTMLElement || selector == window || selector == document){ elements = [selector]; }else if(typeof selector === "string"){ elements = doc.querySelectorAll(selector); } // Push all elements to object if (elements.length) { this.length = elements.length; for (var i = 0; i < this.length; i++) { this[i] = elements[i]; } } return this; } // Append object to window object win.$$ = $$; })(window, document);

Add Methods to Javascript Library using Prototypes

Now that we can select element let's add some functions to our object using prototypes. Notice that our prototype function each: does all the heavy lifting for library. It is serving as a repeatable prototype for other prototypes and calls the callback function provided to it by other prototypes. It calls callback function on every element present in object and passes three values (the current element, the object itself, current index). Now that our library is ready lets use it in our demo.

$$.prototype = {
    each: function (callback) {
        for (var i = 0; i < this.length; i++) {
            callback.call(this[i], this, i);
        }
        return this;
    },
    ready:function(callback){
        return this.each(function(){
            win.addEventListener("DOMContentLoaded",callback,false);
        });
    },
    on: function (name, callback) {
        return this.each(function () {
            return this.addEventListener(name, callback, false);
        });
    },
    hide:function(speed,callback){
        return this.each(function(ob){
            return ob.css("display","none") && ob;
        });
    },
    show:function(speed,callback){
        return this.each(function(ob){
            return ob.css("display","block");
        });
    },
    toggle:function(speed,callback){
        return this.each(function(ob){
            if(!ob.is(":visible")){
                return ob.css("display","block");
            }else{
                return ob.css("display","none");
            }
        });
    },
    is:function(prop){
        switch(prop){
            case ":visible":
                return this[0].clientHeight > 0 && this[0].clientWidth > 0 ? true : false;
                break;
        }
    },
    css:function(param1,param2){
        this.each(function(){
            if(typeof param1 === "object"){
                for(x in param1){
                   this.style[x] = param1[x];
                }
            }
            else if(typeof param1 === "string" && typeof param2 === "string"){
                this.style[param1] = param2;
            }
        });
        return window.getComputedStyle(this[0]).getPropertyValue(param1);
    },
    addClass:function(className){
        return this.each(function(){
            return this.classList.add(className);
        });
    },
    removeClass:function(className){
        return this.each(function(){
            return this.classList.remove(className);
        });
    },
    toggleClass:function(className){
        return this.each(function(){
           if(this.classList.contains(className)){
               return this.classList.remove(className);
           }else{
               return this.classList.add(className);
           }
        });
    }
};

Create an HTML Page to Use Javascript Library

Create an HTML page and some containers with dummy text to test the functionality of our library.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Write a Javascript Library From Scratch - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<script type="text/javascript" src="js/library.js"></script>
<script type="text/javascript" src="js/javascript.js"></script>
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<div class="container">
<div class="mb-4">
<div>
<button class="btn btn-default btn-hide">Hide</button>
<button class="btn btn-default btn-show">Show</button>
<button class="btn btn-default btn-toggle">Toggle</button>
Hide, Show or Toggle paragraph below:
</div>
<div class="p-wrapper">
<p class="hide-show-toggle">
Aenean aliquam libero dolor, vel efficitur leo tempus sit amet. Aliquam erat volutpat. Ut malesuada leo id cursus congue.
Integer congue dolor ac risus laoreet, vitae fringilla dolor tempor. Nunc vitae rutrum elit.
Quisque dolor nulla, vulputate in mi vel, imperdiet tristique metus.
Integer sed ante vel ex elementum placerat sodales ut lectus. Integer sit amet posuere nulla.
Mauris eget lacinia est. Suspendisse laoreet euismod sollicitudin. Donec eu vehicula eros. Nunc mi magna, vestibulum sed scelerisque sed, consequat eu leo.
</p>
</div>
</div>

<div class="mb-4">
<div>
<button class="btn btn-default add-class">Add Class</button>
<button class="btn btn-default remove-class">Remove Class</button>
<button class="btn btn-default toggle-class">Toggle Class</button>
Add, Remove or Toggle class on paragraph below:
</div>

<p class="add-remove-toggle">
Morbi felis diam, ornare et lorem sed, accumsan fermentum nunc.
    Fusce elementum auctor tortor vitae hendrerit. Nunc a tincidunt velit. Duis nec ornare ante, at ullamcorper massa.
    Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam nisl dolor, dapibus eu sollicitudin id, ornare fermentum odio.
    Curabitur laoreet enim enim, a elementum nisl ornare eget. Ut lectus sem, mollis vitae augue ut, consectetur mattis augue. Etiam vel placerat nisi, quis consectetur magna.
    Sed a condimentum ipsum. Phasellus non nisi augue. Donec venenatis metus vel laoreet varius. Curabitur elit risus, vulputate ut sagittis a, placerat quis quam.
</p>
</div>
</div>
</body>
</html>
 

Add CSS Styles

Add needed CSS styles for HTML page and containers used for testing library functionality.

style.css

*{
box-sizing: border-box;
}
html,body{
margin: 0;
padding: 0;
}
body{
background-color: #f6f6f6;
font-family: "Segoe UI", "Roboto", "Helvetica", sans-serif;
font-size: 15px;
font-weight: normal;
font-style: normal;
}
a{
text-decoration: none;
color: #3778cd;
}
.container{
max-width: 1140px;
width: 100%;
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}
.mb-4{
margin-bottom: 1rem;
}
.btn{
display: inline-block;
padding: 5px 10px;
cursor: pointer;
font: inherit;
background: #fff;
border: 1px solid #eee;
}
.bg-color {
background: #006cad;
color: #fff;
}

Use Javascript Library Functions

Implement the functionality for events listeners in javascript.

javascript.js

$$(document).ready(function(){
$$(".btn-hide").on("click",function(){
$$(".hide-show-toggle").hide();
});
$$(".btn-show").on("click",function(){
$$(".hide-show-toggle").show();
});

$$(".btn-toggle").on("click",function(){
$$(".hide-show-toggle").toggle();
});

$$(".add-class").on("click",function(){
$$(".add-remove-toggle").addClass("bg-color");
});
$$(".remove-class").on("click",function(){
$$(".add-remove-toggle").removeClass("bg-color");
});

$$(".toggle-class").on("click",function(){
$$(".add-remove-toggle").toggleClass("bg-color");
});
});