domejs

domejs is a minimal proxying shortcut DOM library. It provides a single function, called $ or dome, that wraps up the repetitive parts of writing DOM code while still looking essentially like standard DOM API usage.

The $ function has two uses: creating new elements (new $('li.important')), and retrieving existing elements to manipulate together ($('input[type=text].search').value = ''). Obtain the code and load the function with import $ from './dome.js', or try it out below.

Creating elements

New elements can be created from CSS selectors that describe them:

new $('a#home.important[href="/"]', 'Home', new $('img[src=/logo.png]'))

creates a new element like

<a id="home" class="important" href="/">Home<img src="/logo.png" /></a>

matching the selector, with the remaining arguments put into the body as with append. These are undecorated DOM elements and can be added to the page immediately. Element, class, ID, and attribute selectors can be combined as needed to describe the element.

Manipulating elements

$ accepts a CSS selector and finds all matching elements on the page. Regardless of how many matching elements there are, they can each have the same operations performed on them in a single line. Properties can be written to with standard assignment or looped over, including nested properties, and standard DOM methods can be called directly across all matching elements.

All of the following work regardless of how many elements match:

$('a').style.color = 'red'
$('#nav > ul').lastElementChild.remove()
for (let s of $('img').src) console.log(s)

An empty ul above will also be handled without error.

Updating properties

Properties can be assigned to just as for a single element, including nested properties:

$('input[type=text]').value = ''

This will empty all text input fields in the page.

$('input.important').style.background = '#fcc'

This will turn the background of all important inputs pink.

Computed updates

To update a property individually, with the new value computed using the old or some other aspect of the element, every property has an update method as well:

$('input[type=number]').value.update(x => x / 2)

This halves the value of all number inputs.

$('input.q').value.update((cur, el) => cur + el.dataset.p)

This changes the value of every input with class q to the concatenation of its current value and the data-p attribute on the element.

$('div').style.width.update(x => Number.parseInt(x) * 2 + 'px')

This doubles the style width of every div on the page.

Iterating over elements and properties

Both the collection of matching elements and properties extracted from an element can be looped over with a for...of loop.

for (let e of $('li')) e.textContent = e.dataset.label;

This loops over every li element on the page, and updates the textContent property of each.

for (let v of $('input.names').value) console.log(v)

This loops over the value of every input with class names, and logs the values one at a time.

Array.from($('input.names').value)

This constructs an array from all of the input values.

Calling methods

Standard DOM methods can be called on all matching elements simply by using them directly, including those accessed through longer property chains.

$('input.important').remove()

This removes all important inputs from the page.

$('a:nth-of-type(2n)').firstChild.classList.toggle('quiet')

This toggles the quiet class on the first child of every second a element on the page.

$('img + caption').parentNode.addEventListener('click', f)

This installs an event listener to the parent node of every image caption.

Event handlers

Two shorthand methods on and off let you add/remove event handlers from a collection of elements. They each support three different equivalent ways of using them:

$('li').on('click', () => alert('clicked'))
$('li').on.click(() => alert('clicked'))
$('li').on.click = () => alert('clicked')

All three of the above attach an event handler to the click event producing an alert.

$('li').off('click', handler)

The off method requires both the event name and the handler to be specified.

Other methods

A few additional methods forEach, map, and filter exist on all collections with the usual meanings. These methods shadow any existing methods or properties on the collection elements with those names.

$('li').forEach(x => alert(x.textContent))
$('img').map(x => {url: x.src, width: x.width })
$('input[type=number]').filter(x => x.value * 10 < 100)

A $ method allows nested queries:

$('img').parentNode.$('p')

Obtaining domejs

The domejs source code is available on GitHub. It can be used with

import $ from './dome.js'

with the path to your local dome.js file, and then used as above.

Try domejs

Code you enter will be executed with eval. Both $ and dome are available. The dashed area above is a div#scratch, which you can fill with useful elements using the button above. Click a single-line sample above to copy it into the textbox to run. The return value of the code is looped over and logged to the browser console. You can also use dome from your browser console directly on this page.

Michael Homer — 2020