Skip to content
Jaakko Alajoki
Jaakko Alajoki, April 23, 2017

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.

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()