Skip to main content

JQuery Like Selector And Events With 30 Line Of JavaScript

We all know how cool the jQuery selector are. We can select any DOM elements with just a $ sign. But jQuery is not always an option for us. Sometimes we need to get our hand wet with vanillaJS.

Selecting DOM elements with vanillaJS is not as cool as jQuery. it's very verbose and requires lot of typing. For selecting a DOM element with id, we need to type document.getElementById('yourid'). You don't like to do it right? Is it really hard to create a shorthand method of selecting DOM elements and binding events? Not really. I will show you how you can write a shorthand method to select DOM element and bind events just like jQuery with just 30 line of code.

Our goal is not creating a feature-rich library like Jquery. We will not even write our code to support legacy browsers and handling errors. Of course, we can do that but I want to keep the code simple and easy to understand for all.

Creating Constructor Function:

Let's start by creating a constructor function named $.

function $(obj) {
  this.el = document.querySelectorAll(obj)
}

We have created a constructor function. Whenever we will create a new object from this constructor function it will assign our DOM elements to its el property.document.querySelectorAll() is our life saver. It does 90% job what jQuery $ do.

Let's create a new object from this constructor

var foo = new $('#myid')

Here #myid is the DOM element id. Every time when we will create a new object from our constructor we need to use this new keyword. Without this new keyword, it simply won't work. because this new operator tells JavaScript that we are going to create a new object. But with a simple trick we can give up with this new keyword and force the creation of a new object in our constructor function.

function $(obj) {
  if(this === window)
    return new $(obj)
  this.el = document.querySelectorAll(obj)
}

If we call our constructor function without the new keyword thenthisoperator will point to the window. And then we will return new $(obj). That way we can force the creation of a new object.

So now we can simply write

var foo =  $('#myid')

If we want to access DOM API then we need to follow this pattern

$('#myid').el[0].innerHTML // accessing native api

It's little awkward because we want to do something like -

$('#myid').innerHTML

It is fine for now. We will solve it at the end of this writing.

Binding Events:

At this point, we will add some static methods to our construction function for handling events. We will only use this static method in our library code.

$._addEvent = function(obj,evt,fn) {
  [].forEach.call(obj, function(el){
    el.addEventListener(evt, fn)
  });
}

We have a method _addEvent and it has three parameters. obj refers to our DOM element,evt is the type of event that we want to register and fn is the callback.

document.querySelectorAll() return an array like object. Yes, I said array like. Not array. It doesn't have array methods like forEach(), indexOf(), etc. forEach access the empty array prototype method and using call allow the nodelist to take advantage. In this forEach loop, it registers events to all the elements that return by the querySelectorAll(). It register event by calling addEventListener with the event and callback function as a parameter.

Add Prototype Methods:

Let's add a prototype methods to our constractor function for handling events.

$.prototype.addEvent = function(evt, fn) {
  $._addEvent(this.el, evt, fn);
  return this;
}

We call the _addEvent static method inside our prtotypeaddEventmethod. we returned this because it will make it chainable.

So far we did a great job now its time to use our code

$('#myid').addEvent('click', function(e){
  this.innerHTML = "codient"
})

Awesome! we have created a shorthand way to select DOM element and register events on it. We can take this awesomeness one step further by adding some more methods.

$.prototype.click = function(fn) {
$._addEvent(this.el, 'click', fn)
  return this;
}
// uses
$('#myid').click(function(e){
  this.innerHTML = "codient"
})

Following the same pattern, you can add all type of event handler in the prototype. But it will be a lot of repetitive code which is against DRY (Don't Repeat Yourself) rules in programming. Why not create an array of all events and loop over them to add methods in prototype?

var events = ['click', 'mouseover', 'keypress']; // Yes, you can add more of them :)
events.forEach(function(event){
  $.prototype[event] = function(fn) {
    $._addEvent(this.el, event, fn)
    return this;
  }
})

Now we have all the event api in our prototype.

Access Node Without Event:

If we want to access native api like this -

$('#myid').innerHTML // Error :(

It won't work. But we can access it through this pattern -

$('#myid').el[0].innerHTML // Works :)

but it is little awkward. I have a very simple and straightforward solution for this problem. We can write a function that will simply return our DOM element.

var _$ = function(node) {
  var type = 'querySelectorAll';

  if (node.indexOf('#') === 0) {
    type = 'getElementById';
    node = node.substr(1, node.length);
  }
  return document[type](node);
};

// Uses
_$('single').innerHTML // works :)

Let's put all the code togather:

Conclusion:

That's it. Now we can select DOM element and register event just like jQuery. Of course, we can improve this code a lot by adding some validation, displaying errors and cross-browser code. But my goal was to show you how easy it is to create a shorthand method of selecting DOM elements without any library. 

Comments

Post a Comment

Popular posts from this blog

Play video while downloading it

You have decided to watch a movie. You go to your favorite movie download site and started downloading it. It will take 2 hours to complete the download. Probably, You will wait 2 hours to watch the movie. Right? Not anymore.You can download and watch the movie simultaneously.  Here's how. Essential software: Internet download manager VLC media player This trick should work on any downloader but I am using IDM here because it's the most popular download manager. I recommended VLC player. It works great in this situation. Other players may or may not work. Software settings: Open IDM and navigate to Download > Options . Now click on the "Connection" tab. Under the max connections number select "Default max conn. number" to "1" .  Its very important because by default IDM use 8 connection to download files from the server. It means IDM download your files on 8 part and when download finished IDM combine the 8 part. But it's im

Top Video Tutorials, Sites And Resources To Learn React

ReactJS was a trading technology of 2016 and 2017 is also a very good time to learn React. On a very short time, I have seen a lot of tech giant companies to move their web application on React. Facebook , Instagram , Dropbox , New York Times , Yahoo Mail and so many big companies are using React right now on production.

Essential Visual Studio Code Extension For Web Designer

Visual studio code is on of the most popular code editor for web designers and developers. It’s simple interface and variety of language support makes it so awesome. In visual studio code, you can use extensions to extend its functionality. There are thousand of extensions are available on visual studio marketplace. But I want to highlight 5 most useful extensions for web designer and developer that will increase productivity.