Modifying DOM elements without a framework can be tedious. The method names are long, and simple common tasks are split into tiny steps.
Wouldn't it be nice if the DOM was a bit more like an Array? Just push a new element, call sort
or even reduce
all the values into one.
As part of a larger project, which I'm writing a longer post about at the moment, I built this convenient little helper that works well enough on its own that I want to write a separate little post about it.
domLense
is a module of less than 100 lines that lets you pretend a DOM element is actually an array. You can index it, push
and pop
values, loop it with forEach
and even map
, reduce
, etc. it to get new values.
The way it works is simple: You tell the module how to get the interesting data from an element, and how to deposit different data back to it. Optionally, you define how new elements should be created.
const transforms = {
get(li) { return li.innerText },
set(li, text) { li.innerText = text },
new() { return document.createElement("li") }
}
In this case, our "interesting data" is just the text content of a bunch of <li>
elements.
All that's left now is to call domLense
on an unsuspecting list element, and we'll be able to treat it just like an array:
const listElement = document.createElement("ol")
const list = domLense(listElement, transforms)
list.push("First item on the list")
list.push("Another item on the list")
list.reverse()
console.log(list.map(text => `* ${text}`).join("\n"))
I've prepared a small codepen demo to play around with this.
The way this works isn't really that complicated. The helper simply creates a proxy that redirects integer indices to the element's child list applying the provided transformations. For any other keys, it tries looking them up in Array.prototype
.