Skip to content

Replacing jQuery with native Javascript in our projects

jQuery was released at 2006. It was initially created to fill gaps between browsers. Today – ten years later – things are quite different. There are no such differences anymore and Javascript is more standardised. So it’s fair to ask if jQuery is needed anymore? It adds a dependency but does it provide enough value? I think we are just used to automatically add it and we never really think if it’s worth of it.

Jaakko Alajoki, April 23, 2017

So I decided to do a small exercise. I took eight of our last projects and searched for jQuery usage with this bash snippet:

find . -path "*assets*.js" | xargs grep -h \$[\(\.]

Then I took most used jQuery commands and searched for native alternatives. This it what I found:


Probably the most common use of jQuery is querying DOM:
$('.element')

There is a direct native equivalent to this:
document.querySelectorAll('.element')


So what about looping through elements?
$('.element').each(function(el) {})

This is little bit trickier since querySelectorAll returns a NodeList, not array. That’s why forEach and for…in loops are unsafe. So far it seems that good old for-loop works the best:
var elements = document.querySelectorAll('.element');
for (var i = 0; i < elements.length; i++) {}


Adding a click event listener:
$('.element').click(function(e) {})

JavaScript equivalent:
document.querySelector('.element').addEventListener('click', function(e) {})


Traversing DOM:
$('.element').parent()
$('.element').next()
$('.element').previous()

Native DOM alternatives:
document.querySelector('.element').parentNode
document.querySelector('.element').nextElementSibling
document.querySelector('.element').previousElementSibling


Modifying attributes:
$('.element').attr('href', 'https://www.evermade.fi')

Plain JavaScript:
document.querySelector('.element').setAttribute('href', 'https://www.evermade.fi');


Modifying data attributes works similarly. In jQuery:
$('.element').data('title', 'Cats & dogs')

And in pure JavaScript:
document.querySelector('.element').setAttribute('data-title', 'Cats & dogs')

And there is also a dataset attribute available:
document.querySelector('.element').dataset.title = 'Cats & dogs'


Manipulating classes:
$('.element').addClass('red')
$('.element').removeClass('red')
$('.element').toggleClass('red')

DOM elements has classList property that can be used to manipulate classes:
document.querySelector('.element').classList.add('red')
document.querySelector('.element').classList.remove('red')
document.querySelector('.element').classList.toggle('red')


Manipulating styles directly:
$('.element').css('font-size', '1rem')

And without jQuery:
document.querySelector('.element').style.fontSize = '1rem'


inArray helper:
$.inArray('dog', ['cat', 'dog', 'rat'])

is same as:
['cat', 'dog', 'rat'].indexOf('dog')


You can animate things with jQuery like this:
$('.element').fadeIn()
$('.element').animate({left: '20px'})
$('.element').stop()

There are no direct JavaScript alternatives to jQuery’s animation functions but you should use CSS animations anyway.


Appending elements:
$('.element').append('<b>2nd element</b>')

Doing exactly the same in JavaScript is a little bit tricky. However you can do most of this kind of stuff with setting innerHTML-property.
var el = document.createElement('b');
el.innerHTML = '2nd element';
document.querySelector('.element').append(el);


So we already saw this on the previous point:
$('.element').html('<b>2nd element</b>')

And alternatively:
document.querySelector('.element').innerHTML = '<b>2nd element</b>'


You can easily check element visibility in jQuery by:
$('.element').is(":visible")

There is no direct alternative to this on pure JavaScript. Solution depends on how you have hidden your element. You can use for example one of these:
document.querySelector('.element').style.display == 'none'
document.querySelector('.element').classList.contains('hidden')


Lastly making an ajax request:
$.ajax({
++url: url,
++success: function(response) {
++++console.log(response);
++}
);

You can use native XMLHttpRequest to do the request:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
++if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
++++console.log(xmlhttp.responseText);
++}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();

Search