Create a JavaScript Library From Scratch

Almost every web developer has encountered the use of jQuery in everyday coding. This post is about how to create a JavaScript library like jQuery from scratch with selectors, event handlers, show/hide, CSS utilities, and more.

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 to serve their purpose and functionality. This post demonstrates how to create a JavaScript library of your own. We will create a JS library replicating a few features of jQuery as an example. We will be using the IIFE (Immediately Invoked Function Expression) approach to initialize our library.

It is going to be a small and simple library just to illustrate the basic working model of jQuery. First, we are going to create a JS object, and we are going to use $$ as the object name. We will be using an Immediately Invoked Function Expression to create the instance of our library object. Let us start by  defining our object using a self-invoking function that accepts a selector as a parameter.

 

Create JavaScript Library Definition with Self-Invoking Function

This code snippet is the basic implementation of our library that accepts selectors. We can select elements like jQuery using $$("p"), $$(window), $$(document), etc. A brief step-by-step explanation of the code below is:

  • Call the self-invoking function with the provided parameters, window, and document object.
  • Check if the $$ is called as a constructor. If not, then create a new instance of $$.
  • Set up this and the elements array for storing selected elements.
  • Define various types of selectors, including HTML elements and a selector as a string.
  • Select all elements and append them to the elements array.
  • Append the $$ object to the 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;
let 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 (let i = 0; i < this.length; i++) {
this[i] = elements[i];
}
}
return this;
}
// Append object to window object
win.$$ = $$;
})(window, document);

Write a JavaScript Library using Prototypes

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

$$.prototype = {
each: function (callback) {
for (let 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 a JavaScript Library

Create an HTML page user interface and some containers with sample text to test the functionality of our library. We will check the hide/show/toggle and add/remove/toggle CSS class in our example.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Create a Javascript Library From Scratch - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport"/>
<link rel="stylesheet" href="css/style.css"/>
<script src="js/library.js" type="text/javascript"></script>
<script src="js/javascript.js" type="text/javascript"></script>
</head>
<body>
<section class="section py-4">
<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>
</section>
</body>
</html>
 

Add CSS Styles

Add needed CSS styles for the HTML page and containers used in our sample to test 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;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.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;
}

Example Usage of JavaScript Library

This code block will actually add event listeners using the JavaScript library we just created. We will listen to certain events and bind them to trigger some functions like hide, show, toggle, etc. 

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");
});
});