What are some techniques for creating a jQuery-like fluent interface?
At the heart of this question is the notion of abstracting over a selection of NodeList
s and doing DOM changes on all the nodes in them. jQuery is usually exposed by the name $
, and typical code might look like this1:
$ ('.nav li:first-child a')
.color ('red')
.size (2, 'em')
.click ((evt) => {
evt .preventDefault ();
console .log (`"${evt .target .closest ('a') .textContent}" link clicked`)
})
Note the fluent interface there. The nodes are selected once, and then the functions color
, size
, and click
are executed against each matching node. The question, then, is how can we build such a system that allows us to write simple versions of color
, size
, and click
which are bound together in a common chained interface?
In response to a similar question (now deleted), I wrote my own version, and user @WillD linked to a JSFiddle, which I'm hoping will become another answer.
For this pass, I'm suggesting that we don't try to mimic other parts of jQuery's functionality; certainly not things like .ajax
or $(document).ready(...)
, but also to not bother with the plug-in mechanism (unless it comes for free) or the ability to generate a new NodeList
from the current one.
How would one go about turning a collection of functions into a function that generates a collection of nodes from a selector and allows you to chain those functions as methods on this collection.
1This library long predated document.querySelector/querySelectorAll
, and I'm assuming it was a large part of the inspiration for the DOM methods.