Last active
September 21, 2023 23:05
-
-
Save AlexVipond/2f135c84e673e80e7bc8452de349cae4 to your computer and use it in GitHub Desktop.
JFunky - JQuery-inspired library for manipulating the DOM with unary functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function $ (selector: string) { | |
| return function (ancestors: [Document] | HTMLElement[] = [document]) { | |
| return [ | |
| ...ancestors.flatMap( | |
| ancestor => [...ancestor.querySelectorAll(selector)] as HTMLElement[] | |
| ) | |
| ] | |
| } | |
| } | |
| function at (index: number) { | |
| return function (elements: HTMLElement[]) { | |
| return [elements.at(index)] | |
| } | |
| } | |
| function clone (options: { depth?: 'shallow' | 'deep' } = { depth: 'deep' }) { | |
| const { depth } = options | |
| return function (elements: HTMLElement[]) { | |
| return elements.map(element => element.cloneNode(depth === 'deep')) | |
| } | |
| } | |
| function template (options: { clone?: Parameters<typeof clone>[0] } = {}) { | |
| const { clone: cloneOptions } = options | |
| return function (elements: HTMLTemplateElement[]) { | |
| return clone(cloneOptions)( | |
| elements.flatMap( | |
| element => [...element.content.children] as HTMLElement[] | |
| ) | |
| ) | |
| } | |
| } | |
| function on ( | |
| event: string, | |
| options: { | |
| effect?: (event: Event) => void, | |
| } & AddEventListenerOptions = { effect: () => {} }, | |
| ) { | |
| const { effect, ...addEventListenerOptions } = options | |
| return function (elements: HTMLElement[]) { | |
| for (const element of elements) { | |
| // @ts-expect-error | |
| element.addEventListener(event, effect, addEventListenerOptions) | |
| } | |
| return elements | |
| } | |
| } | |
| function off ( | |
| event: string, | |
| options: { | |
| effect?: (event: Event) => void, | |
| } & EventListenerOptions = { effect: () => {} }, | |
| ) { | |
| const { effect, ...removeEventListenerOptions } = options | |
| return function (elements: HTMLElement[]) { | |
| for (const element of elements) { | |
| // @ts-expect-error | |
| element.removeEventListener(event, effect, removeEventListenerOptions) | |
| } | |
| return elements | |
| } | |
| } | |
| function root () { | |
| return function (elements: HTMLElement[]) { | |
| const roots: HTMLElement[] = [] | |
| for (const element of elements) { | |
| let r = element | |
| while (r.parentElement) { | |
| r = r.parentElement | |
| } | |
| roots.push(r) | |
| } | |
| return roots | |
| } | |
| } | |
| function appendTo (selector: string) { | |
| const container = pipe( | |
| $(selector), | |
| selected => selected.at(0), | |
| )() as HTMLElement | |
| return function (elements: HTMLElement[]) { | |
| for (const element of elements) { | |
| container.appendChild(element) | |
| } | |
| return elements | |
| } | |
| } | |
| function pipe (...fns: Function[]) { | |
| return function (value?: any) { | |
| return fns.reduce((acc, fn) => fn(acc), value) | |
| } | |
| } | |
| const thing = pipe( | |
| $('#my-template'), | |
| template(), | |
| $('.btn'), | |
| at(0), | |
| on('click', { effect: () => console.log('clicked') }), | |
| root(), | |
| appendTo('.container'), | |
| )() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment