dollar.ts
π² takes this:
const el: HTMLElement = document.querySelector(".class");
el.innerHTML = "hi mom!";
el.style.transform = "translateX(100px)";
el.style.color = "red";
el.setAttribute("msg", "hi dad!");
and transforms it to this:
$<HTMLElement>(".class").setattr({
html: "hi mom!",
styles: {
transform: "translateX(100px)",
color: "red"
},
msg: "hi dad!"
});
WHAT more lines?! Yep.
The rather verbose syntax of
document.querySelector[All]
caused a recent project to become cluttered and downright unintelligible in places. Additionally, the common operation of modifying CSS attributes was a major pain:
el.style.$prop = `${$value}`;
// or dynamically, as
el.style.setProperty($prop, $value);
// and this is just for one attribute!
Inspired, I spent a few hours creating yet another jQuery replacement... with its one and only library file dollar.ts. The goal of this was to turn something like this:
Array.from(document.querySelectorAll(".class")).forEach((el) => {
el.style.height = "100px";
});
into this:
$$<HTMLElement>(".class").css({ height: "100px" });
Where the double dollar $$
syntax selects all nodes of that query.
While also providing the type safety and code completion the former offers through standard TypeScript. The end product does just that, but comes with a few caveats:
The input object to a call of $
must be, at the minimum, derived from the EventTarget
base class.
To enhance the typing functionality, you can manually specify the input node type like so (an example with an HTMLCanvas
element):
const canvasEl = $<HTMLCanvasElement>("canvas");
...
Which will net you all of the standard HTMLCanvasElement
information + a few specializations DollarHTMLElement
provides (explained, too, below).
-
π² Terse query selector syntax of
$("...")
to select one node, or$$("...")
to select multiple. -
π΅
DollarHTMLElement
s contains the following function prototypes:on
: suped-up version ofaddEventListener
that handles multiple events (separated by a space).off
:removeEventListener
variant of the above.setattr
: shorthand for setting multiple attributes with anAttribute
typed object. Smarter in the sense that it can detect specializedElement
types and set their attributes accordingly.css
: shorthand for$.setattr({style: {...}})
; sets thestyle
attribute of anHTMLElement
.html
: shorthand for$.setattr({html: ...})
; sets theinnerHTML
attribute of anHTMLElement
.
-
π Code size: the entire library is ~200 lines, with the majority of that being dedicated to the typing functionality. Yes, there are other libraries that are far more generalized and robust, but that's not our goal here.
-
π An easy way to confound and confuse people into thinking you're using jQuery. But of course you're not, it's
$current_year
! (satire π)
If the input type T
is of a small subset of types, we define a few specialization functions; they are as follows:
- if
T
is a child ofEventTarget
, we provide the following methods:on
off
- if
T
is a child ofElement
, we provide the following methods:setattr
- if
T
is a child ofHTMLElement
, we provide the following methods:css
- a
setattr
which further specializes the keywords:html
styles
Notice the usage of the if
and not else if
qualifier: for example, as HTMLElement
is a child of all of the above, it, too, gains access to all of the above functionality.
$<HTMLElement>(".money").css({ color: "red" });
$$<HTMLElement>(".dollar").css({ height: "50%" }).on("click mousedown", (ev) => {...});
why this is normally so complicated is beyond me
$(window).on("click touchstart", (ev) => {...})