Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Moving to plain JavaScript

Everything jQuery does, the browser can now do by itself. Dropping the library makes the page about 30 KB smaller (compressed) and removes a dependency. You do not have to rewrite the whole project: code is moved over gradually, one file at a time.

Equivalents table

jQueryPlain JavaScript
$(function () {})document.addEventListener('DOMContentLoaded', fn)
$('#tasks')document.querySelector('#tasks')
$('li')document.querySelectorAll('li')
$el.find('li')el.querySelectorAll('li')
$el.closest('li')el.closest('li')
$el.parent()el.parentElement
$el.text()el.textContent
$el.html()el.innerHTML
$el.attr('href')el.getAttribute('href')
$el.prop('checked')el.checked
$el.data('id')el.dataset.id (a string)
$el.addClass('done')el.classList.add('done')
$el.toggleClass('done')el.classList.toggle('done')
$el.css('color', 'red')el.style.color = 'red'
$('<li>')document.createElement('li')
$list.append($item)list.append(item)
$el.remove()el.remove()
$el.on('click', fn)el.addEventListener('click', fn)
$list.on('click', 'li', fn)a handler on list checking event.target.closest('li')
$input.val()input.value
$form.serialize()new URLSearchParams(new FormData(form)).toString()
$('li').each(fn)document.querySelectorAll('li').forEach(fn)
$.getJSON(url)fetch(url).then((r) => r.json())
$el.fadeOut()a CSS transition or el.animate()
$.extend({}, a, b){ ...a, ...b }
$.Deferred()new Promise()

The to-do list without jQuery

The same to-do list as in the delegation lesson, without the library:

<style>
  .done { text-decoration: line-through; color: gray; }
</style>
 
<input id="title" placeholder="New task">
<button id="add">Add</button>
<ul id="tasks"></ul>
 
<script>
  const list = document.querySelector('#tasks');
  const input = document.querySelector('#title');
 
  document.querySelector('#add').addEventListener('click', () => {
    const item = document.createElement('li');
    const title = document.createElement('span');
    title.className = 'title';
    title.textContent = input.value;
 
    const button = document.createElement('button');
    button.className = 'delete';
    button.textContent = 'Delete';
 
    item.append(title, ' ', button);
    list.append(item);
  });
 
  list.addEventListener('click', (event) => {
    if (event.target.closest('.delete')) {
      event.target.closest('li').remove();
    } else if (event.target.closest('.title')) {
      event.target.closest('.title').classList.toggle('done');
    }
  });
</script>

It behaves the same: tasks are added, marked with a click and removed with the button. There is a little more code, but it does not depend on a library.

How to migrate

  1. Write new code without jQuery.
  2. Convert old files one by one, checking the page after each.
  3. Search the project for remaining $( and jQuery( calls. When none are left, remove the jQuery <script> tag.
  4. Replace jQuery plugins (sliders, masks) with modern dependency-free libraries; while they remain, jQuery cannot be removed.

If you need to upgrade jQuery to a newer version rather than remove it, the official jQuery Migrate plugin helps: it prints warnings about deprecated calls to the console.

Common mistake

Carrying over the habit of acting on the whole set: document.querySelectorAll('li').classList.add('done'). The list returned by querySelectorAll() has no classList, so this throws. Without jQuery each element is handled in a loop: document.querySelectorAll('li').forEach((li) => li.classList.add('done')). Also remember that querySelector() returns null when nothing is found, whereas an empty jQuery set silently did nothing.

Thanks for reading!

Donate to the site — we work hard for you.