Every jQuery 561 idiom has a native counterpart. When porting, remember that querySelectorAll() returns a static NodeList whose methods do not apply to every element (loop with forEach), and querySelector() returns null rather than an empty set, so guard with optional chaining: el?.remove().
| jQuery | Vanilla JavaScript |
|---|---|
| $('.a'), $el.find('.a') | document.querySelectorAll('.a'), el.querySelectorAll('.a') |
| $el.closest('li'), $el.parent() | el.closest('li'), el.parentElement |
| $el.next(), $el.is('.on') | el.nextElementSibling, el.matches('.on') |
| $el.each(fn) | list.forEach(fn) |
| $el.append(html) | el.insertAdjacentHTML('beforeend', html) |
| .before(), .after(), .remove() | Same names on Element (Adding and Removing Nodes) |
| $el.empty(), $el.clone() | el.replaceChildren(), el.cloneNode(true) |
| $el.text(), $el.html(), $el.val() | el.textContent, el.innerHTML, el.value |
| $el.attr(n, v), $el.data('k') | el.setAttribute(n, v), el.dataset.k |
| $el.addClass('a'), .toggleClass('a') | el.classList.add('a'), .toggle('a') |
| $el.css('color', 'red'), .css('color') | el.style.color = 'red', getComputedStyle(el).color |
| $el.outerWidth(), $el.offset() | el.offsetWidth, el.getBoundingClientRect() |
| $el.hide(), $el.fadeIn(400) | el.hidden = true, el.animate([{ opacity: 0 }, { opacity: 1 }], 400) |
| $el.on('click', fn), .one('click', fn) | el.addEventListener('click', fn), plus { once: true } |
| $ul.on('click', 'li', fn) | Listener on ul checking e.target.closest('li') |
| $el.trigger('saved', data) | el.dispatchEvent(new CustomEvent('saved', { detail, bubbles: true })) |
| $(fn) | <script defer> or DOMContentLoaded |
| $.getJSON(url) | fetch(url).then((r) => r.json()) (AJAX with Fetch) |
| $form.serialize(), $.param(obj) | new URLSearchParams(new FormData(form)), new URLSearchParams(obj) |
| $.Deferred(), $.when(a, b) | Promise.withResolvers(), Promise.all([a, b]) |
| $.extend(true, {}, obj) | structuredClone(obj) |