Skip to content

Instantly share code, notes, and snippets.

@LachlanArthur
Last active February 24, 2018 16:53
Show Gist options
  • Select an option

  • Save LachlanArthur/a42e534abb67dfdae0d8f212f515e6ec to your computer and use it in GitHub Desktop.

Select an option

Save LachlanArthur/a42e534abb67dfdae0d8f212f515e6ec to your computer and use it in GitHub Desktop.
JS Helpers - Simple functions, sane types

JS Helpers

Simple functions, sane types

$() & $$()

$( 'body' );
$$( 'button' );
$$<HTMLInputElement>( 'form#contact input' );

on()

on( document, 'DOMContentLoaded', () => { } );
on( Array.from( $$( 'img' ) ), 'load', function( e ) { } );
on( $$<HTMLAnchorElement>( 'a.track' ), 'click', function( e ) { } );
import { $, $$, on } from './helpers';
// Auto-detects type with simple tag selectors
let body = $( 'body' ); // HTMLBodyElement | null
let headings = $$( 'h1' ); // NodeListOf<HTMLHeadingElement>
// Use type assertion with CSS selectors
let youtubeEmbeds = $$<HTMLIFrameElement>( 'iframe[src^="https://www.youtube.com/embed"]' ); // NodeListOf<HTMLIFrameElement>
// Tag and event types are passed to the handler:
on( document, 'DOMContentLoaded', function ( e ) {
this; // Document
e; // Event
} );
on( $( 'body' ), 'click', function ( e ) {
this; // HTMLBodyElement
e; // MouseEvent
} );
on( $$<HTMLInputElement>( 'form input[type="email"]' ), 'keydown', function ( e ) {
this; // HTMLInputElement
e; // KeyboardEvent
} );
on( [ $( 'some-custom-element' ), document.body ], 'some-custom-event', function ( e ) {
this; // HTMLElement
e; // Event
} );
declare function $<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
declare function $<E extends HTMLElement = HTMLElement>(selectors: string): E | null;
declare function $$<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;
declare function $$<E extends HTMLElement = HTMLElement>(selectors: string): NodeListOf<E>;
declare function on<E extends HTMLElement, K extends keyof HTMLElementEventMap>(elements: E | null, type: K, listener: (this: E, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
declare function on<E extends HTMLElement>(elements: E | null, type: string, listener: (this: E, ev: Event) => any, options?: boolean | AddEventListenerOptions): void;
declare function on<E extends HTMLElement, K extends keyof HTMLElementEventMap>(elements: NodeListOf<E>, type: K, listener: (this: E, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
declare function on<E extends HTMLElement>(elements: NodeListOf<E>, type: string, listener: (this: E, ev: Event) => any, options?: boolean | AddEventListenerOptions): void;
declare function on<E extends HTMLElement, K extends keyof HTMLElementEventMap>(elements: Array<E | null>, type: K, listener: (this: E, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
declare function on<E extends HTMLElement>(elements: Array<E | null>, type: string, listener: (this: E, ev: Event) => any, options?: boolean | AddEventListenerOptions): void;
declare function on<K extends keyof HTMLElementEventMap>(elements: Document, type: K, listener: (this: Document, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
declare function on(elements: Document, type: string, listener: (this: Document, ev: Event) => any, options?: boolean | AddEventListenerOptions): void;
export { $, $$, on };
function $(selectors) {
return document.querySelector(selectors);
}
function $$(selectors) {
return document.querySelectorAll(selectors);
}
function on(elements, type, listener, options) {
if (elements instanceof NodeList || Array.isArray(elements)) {
Array.from(elements).filter(Boolean).forEach(e => e.addEventListener.call(e, type, listener, options));
}
else if (elements instanceof HTMLElement || elements instanceof Document) {
elements.addEventListener.call(elements, type, listener, options);
}
}
export { $, $$, on, };
// Known tag name
function $<K extends keyof HTMLElementTagNameMap>( selectors: K ): HTMLElementTagNameMap[ K ] | null;
// Any selector
function $<E extends HTMLElement = HTMLElement>( selectors: string ): E | null;
function $<E extends HTMLElement = HTMLElement>( selectors: string ): E | null {
return document.querySelector( selectors );
}
// Known tag name
function $$<K extends keyof HTMLElementTagNameMap>( selectors: K ): NodeListOf<HTMLElementTagNameMap[ K ]>;
// Any selector
function $$<E extends HTMLElement = HTMLElement>( selectors: string ): NodeListOf<E>;
function $$<E extends HTMLElement = HTMLElement>( selectors: string ): NodeListOf<E> {
return document.querySelectorAll( selectors );
}
// Result of $ - known event
function on<E extends HTMLElement, K extends keyof HTMLElementEventMap>( elements: E | null, type: K, listener: ( this: E, ev: HTMLElementEventMap[ K ] ) => any, options?: boolean | AddEventListenerOptions ): void;
// Result of $ - unknown event
function on<E extends HTMLElement>( elements: E | null, type: string, listener: ( this: E, ev: Event ) => any, options?: boolean | AddEventListenerOptions ): void;
// Result of $$ - known event
function on<E extends HTMLElement, K extends keyof HTMLElementEventMap>( elements: NodeListOf<E>, type: K, listener: ( this: E, ev: HTMLElementEventMap[ K ] ) => any, options?: boolean | AddEventListenerOptions ): void;
// Result of $$ - unknown event
function on<E extends HTMLElement>( elements: NodeListOf<E>, type: string, listener: ( this: E, ev: Event ) => any, options?: boolean | AddEventListenerOptions ): void;
// Array of elements - known event
function on<E extends HTMLElement, K extends keyof HTMLElementEventMap>( elements: Array<E | null>, type: K, listener: ( this: E, ev: HTMLElementEventMap[ K ] ) => any, options?: boolean | AddEventListenerOptions ): void;
// Array of elements - unknown event
function on<E extends HTMLElement>( elements: Array<E | null>, type: string, listener: ( this: E, ev: Event ) => any, options?: boolean | AddEventListenerOptions ): void;
// Document - known event
function on<K extends keyof HTMLElementEventMap>( elements: Document, type: K, listener: ( this: Document, ev: HTMLElementEventMap[ K ] ) => any, options?: boolean | AddEventListenerOptions ): void;
// Document - unknown event
function on( elements: Document, type: string, listener: ( this: Document, ev: Event ) => any, options?: boolean | AddEventListenerOptions ): void;
function on<E extends HTMLElement>( elements: E | NodeListOf<E> | Array<E | Document | null> | Document | null, type: string, listener: ( this: E | Document, ev: Event ) => any, options?: boolean | AddEventListenerOptions ): void {
if ( elements instanceof NodeList || Array.isArray( elements ) ) {
Array.from( elements ).filter( Boolean ).forEach( e => e!.addEventListener.call( e, type, listener, options ) );
} else if ( elements instanceof HTMLElement || elements instanceof Document ) {
elements.addEventListener.call( elements, type, listener, options );
}
}
export {
$,
$$,
on,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment