diff --git a/index.ts b/index.ts index 14cca15..0bd1de6 100644 --- a/index.ts +++ b/index.ts @@ -1,5 +1,7 @@ import type {ParseSelector} from 'typed-query-selector/parser'; +// eslint-disable-next-line @typescript-eslint/ban-types -- It's a single property, no mistakes possible +export type DelegateOptions = boolean | Omit; export type EventType = keyof GlobalEventHandlersEventMap; type GlobalEvent = Event; @@ -82,7 +84,7 @@ function safeClosest(event: Event, selector: string): Element | void { /** * Delegates event to a selector. - * @param options A boolean value setting options.capture or an options object of type AddEventListenerOptions + * @param options A boolean value setting options.capture or an options object of type AddEventListenerOptions without the `once` option */ function delegate< Selector extends string, @@ -93,7 +95,7 @@ function delegate< selector: Selector, type: TEventType, callback: delegate.EventHandler, - options?: boolean | AddEventListenerOptions + options?: DelegateOptions ): delegate.Subscription; function delegate< @@ -104,7 +106,7 @@ function delegate< selector: string, type: TEventType, callback: delegate.EventHandler, - options?: boolean | AddEventListenerOptions + options?: DelegateOptions ): delegate.Subscription; // This type isn't exported as a declaration, so it needs to be duplicated above @@ -116,7 +118,7 @@ function delegate< selector: string, type: TEventType, callback: delegate.EventHandler, - options?: boolean | AddEventListenerOptions + options?: DelegateOptions ): delegate.Subscription { // Handle Selector-based usage if (typeof base === 'string') { @@ -160,6 +162,11 @@ function delegate< } }; + // Drop unsupported `once` option https://github.com/fregante/delegate-it/pull/28#discussion_r863467939 + if (typeof options === 'object') { + delete (options as AddEventListenerOptions).once; + } + const setup = JSON.stringify({selector, type, capture}); const isAlreadyListening = editLedger(true, baseElement, callback, setup); const delegateSubscription = { diff --git a/readme.md b/readme.md index 7ea625a..4b292ea 100644 --- a/readme.md +++ b/readme.md @@ -52,6 +52,23 @@ delegate(document.querySelectorAll('.container'), '.btn', 'click', event => { }); ``` +#### With listener options + +```js +delegate(document.body, '.btn', 'click', event => { + console.log(event.delegateTarget); +}, true); + +// Or equivalent: +delegate(document.body, '.btn', 'click', event => { + console.log(event.delegateTarget); +}, { + capture: true +}); +``` + +**Note:** the `once` option is currently not supported. + ### Remove event delegation ```js diff --git a/test.js b/test.js index cee71e8..a5c6321 100644 --- a/test.js +++ b/test.js @@ -123,3 +123,12 @@ test.serial('should not fire when the selector matches an ancestor of the base e anchor.click(); t.true(spy.notCalled); }); + +test.serial('should not consider the `once` option', t => { + const spy = sinon.spy(); + delegate(container, 'a', 'click', spy, {once: true}); + + anchor.click(); + anchor.click(); + t.true(spy.calledTwice); +});