UNPKG

@aws-amplify/analytics

Version:

Analytics category of aws-amplify

52 lines (45 loc) 1.78 kB
/** * Copyright (c) 2017, Philip Walton <philip@philipwalton.com> */ import { closest } from './closest'; import { matches } from './matches'; /** * Delegates the handling of events for an element matching a selector to an * ancestor of the matching element. * @param {!Node} ancestor The ancestor element to add the listener to. * @param {string} eventType The event type to listen to. * @param {string} selector A CSS selector to match against child elements. * @param {!Function} callback A function to run any time the event happens. * @param {Object=} opts A configuration options object. The available options: * - useCapture<boolean>: If true, bind to the event capture phase. * - deep<boolean>: If true, delegate into shadow trees. * @return {Object} The delegate object. It contains a destroy method. */ export function delegate(ancestor, eventType, selector, callback, opts = {}) { // Defines the event listener. const listener = function(event) { let delegateTarget; // If opts.composed is true and the event originated from inside a Shadow // tree, check the composed path nodes. if (opts['composed'] && typeof event['composedPath'] === 'function') { const composedPath = event.composedPath(); for (let i = 0, node; (node = composedPath[i]); i++) { if (node.nodeType === 1 && matches(node, selector)) { delegateTarget = node; } } } else { // Otherwise check the parents. delegateTarget = closest(event.target, selector, true); } if (delegateTarget) { callback.call(delegateTarget, event, delegateTarget); } }; ancestor.addEventListener(eventType, listener, opts['useCapture']); return { destroy: () => { ancestor.removeEventListener(eventType, listener, opts['useCapture']); }, }; }