Selecting elements (part 1)
| 1 min read | JavaScript Framework Diet 2/10
Lets get warmed up! Before we can get productive, we need two small helpers that we’ll be using in most components we’ll build from here on. I’m talking about $
and $$
, which are wrappers around document.querySelector
and document.querySelectorAll
.
function $(selector, scope = document) {
return scope.querySelector(selector);
}
function $$(selector, scope = document) {
return Array.from(scope.querySelectorAll(selector));
}
Why bother since they’re near aliases of their native counterparts? One of the reasons we declare these is because the native functions names are so damn long. It’s not about laziness, the verbosity of the native functions hurts readability.
$
selects a single occurrence of an element that matches a given selector.
function $(selector, scope = document) {
return scope.querySelector(selector);
}
const map = $('[data-map]');
By default, $
looks for a matching element across the entire document. Use the optional scope
argument to look for an element inside another.
<div data-map>
<div data-map-marker></div>
</div>
const map = $('[data-map]');
const marker = $('[data-map-marker]', map);
$$
selects all occurrences of an element that matches a given selector.
function $$(selector, scope = document) {
return Array.from(scope.querySelectorAll(selector));
}
const imageGalleries = $$('[data-image-gallery]');
This one contains a bit more plumbing than $
. document.querySelectorAll
returns a NodeList
object, which doesn’t provide any array functions like map
and forEach
(in most browsers at least). Before returing the result, the NodeList
gets transformed to an array, which is way more useful.
$$('[data-image-gallery]').forEach(imageGallery => {
//
});
Just like $$
it can accept a scope as its second argument.
<ul data-image-gallery>
<li><img></li>
<li><img></li>
</ul>
$$('[data-image-gallery]').forEach(imageGallery => {
const images = $$('img', imageGallery);
//
});
Browsers also have more specific functions to target nodes like getElementById
and getElementsByClassName
. These are more than twice as fast as querySelector
, should we use those instead?
querySelector
can run over thousands times per millisecond. This is probably more than fast enough for your application. If you’re writing low level framework code, it’s a different story, but for application development, querySelector
is cheap enough.
In Chris Ferdinandi’s words: It’s not slow. It’s just not as fast.
These selector functions will be one of the main building blocks for the vanilla JS components we’ll be creating over the next few weeks.
JavaScript Framework Diet
JavaScript frameworks are great, but overused. Adding small bits of interactivity to an interface shouldn’t mean installing kilobytes of dependencies or introducing complex build tools.
It’s time for a diet. I’m challenging you to build something without a framework, or follow along and learn something along the way.
Series under development, posts are added on a weekly basis.
I occasionally send out a newsletter with personal stories, things I’ve been working on in the past month, and interesting things I come across.
Pinky swear that I won't use your data for any other purposes. Your email address will be stored on Mailchimp and nowhere else.
Catalin Prodan
2020-02-08 10:52