Import functions:

import { closest, matches } from '/dom/module.js';

All functions that take more than one parameter are partially applicable.


closest(selector, node)

Returns the node itself or the closest ancestor that matches selector. If no match is found, returns undefined.


attribute(name, node)

Returns the string contents of attribute name. If the attribute is not set, returns undefined.


Returns the id of node, or where node has no id, a random id is generated, checked against the DOM for uniqueness, set on node and returned:

// Get ids of all buttons in document
select('button', document)
.forEach((id) => ...)

media(query, enterFn, exitFn)

Evaluates query object, which is an object describing a media and scroll query, against the document, and calls enterFn when all conditions in the selector object become true, and exitFn when at least one of them becomes false.

A query object may contain any combination of the properties:

    minWidth: number | string | fn,
    maxWidth: number | string | fn,
    minHeight: number | string | fn,
    maxHeight: number | string | fn,
    minScrollTop: number | string | fn,
    maxScrollTop: number | string | fn,
    minScrollBottom: number | string | fn,
    maxScrollBottom: number | string | fn

For each property a number represents a value in pixels, a string must be a value with CSS units (eg. '3rem'), or a function must return a number representing a value in pixels.


Returns the tag name of node, in lowercase.

const li = create('li', 'Salt and vinegar');
tag(li);   // 'li'


Returns one of 'element', 'text', 'comment', 'document', 'doctype' or 'fragment'.


assign(node, properties)

Assigns each property of properties to node, as a property where that property exists in node, otherwise as an attribute.

If properties has a property 'children' it must be an array of nodes; they are appended to ‘node’.

The property 'html' is treated as an alias of 'innerHTML'. The property 'tag' is treated as an alias of 'tagName' (which is ignored, as node.tagName is read-only). The property 'is' is also ignored.

create(tag, content)

Constructs and returns a new DOM node.

  • If tag is "text" a text node is created.
  • If tag is "fragment" a fragment is created.
  • If tag is "comment" a comment is created.
  • If tag is any other string the element <tag></tag> is created.
  • Where tag is an object, it must have a "tag" or "tagName" property. A node is created according to the above rules for tag strings, and other properties of the object are assigned with dom’s assign(node, object) function.

If content is a string it is set as text content on a text or comment node, or as inner HTML on an element or fragment. It may also be an object of properties which are assigned with dom’s assign(node, properties) function.


events(type, node)

Returns a mappable stream of events heard on node:

var stream = events('click', document.body);
.each(function(node) {
    // Do something with nodes

Stopping the stream removes the event listeners:



Returns true if user event is from the primary (normally the left or only) button of an input device. Use this to avoid listening to right-clicks.

gestures(options, node)

Returns a stream of streams of events. Each stream of events represents the motion of a single finger. The types of events the stream contains is either 'mousedown' followed by any number of 'mousemove's and a 'mouseup', or the touch objects that go with 'touchstart', any number of 'touchmove's and a 'touchend'.

gestures({ selector: '.thing', threshold: '0.5rem' }, document)
.each(function(events) {
    // First event is a mousedown or touchstart event
    const e0 = events.shift();

    events.each(function(e1) {
        // Mousemove or touchmove events
        const distance = Math.pow(
            Math.pow(e1.clientX - e0.clientX, 2),
            Math.pow(e1.clientY - e0.clientY, 2),


Constrains focus to focusable elements inside node. Returns a function that removes the trap. Calling trapFocus(node) again also removes the existing trap.


Returns key string corresponding to e.keyCode, or undefined.



Returns a prefixed CSS property name where a prefix is required in the current browser.


Returns a DOMRect object describing the draw rectangle of node. (If node is window a preudo-DOMRect object is returned).


Disables scrolling by setting overflow: hidden on node while maintaining the current scrollTop, effectively causing the node to ‘freeze’ in position.

style(property, node)

Returns the computed style property of node.

style('transform', node);            // returns transform

If property is of the form "property:name", a named aspect of the property is returned.

style('transform:rotate', node);     // returns rotation, as a number, in radians
style('transform:scale', node);      // returns scale, as a number
style('transform:translateX', node); // returns translation, as a number, in px
style('transform:translateY', node); // returns translation, as a number, in px


animate(duration, transform, name, object, value)

Animates property name of object to value over duration seconds, using the transform function as an easing function, and updates the object on animation frames.

duration  - number in seconds
transform - function that maps x (0-1) to y (0-1)
name      - string name of property to animate
object    - object to animate
value     - target value

transition(duration, fn)

Calls fn on each animation frame until duration seconds has elapsed. fn is passed a single argument progress, a number that ramps from 0 to 1 over the duration of the transition. Returns a function that cancels the transition.

transition(3, function(progress) {
    // Called every frame for 3 seconds



request(type, url, data, mimetype | headers)

Uses fetch() to send a request to url. Where type is "GET", data is serialised and appended to the URL, otherwise it is sent as a request body. The 4th parameter may be a content type string or a headers object (in which case it must have a 'Content-Type' property).