From a3398fffd6e5b73a6a2cc2a1fc454ab199b2bf82 Mon Sep 17 00:00:00 2001 From: Johann-S Date: Wed, 23 Aug 2017 12:01:38 +0200 Subject: [PATCH] Add event delegation + fix EventHandler.one --- js/src/alert.js | 7 +------ js/src/dom/eventHandler.js | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/js/src/alert.js b/js/src/alert.js index 4a63b1737d..5e99f6d011 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -153,12 +153,7 @@ class Alert { * Data Api implementation * ------------------------------------------------------------------------ */ - -$(document).on( - Event.CLICK_DATA_API, - Selector.DISMISS, - Alert._handleDismiss(new Alert()) -) +EventHandler.on(document, Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())) /** * ------------------------------------------------------------------------ diff --git a/js/src/dom/eventHandler.js b/js/src/dom/eventHandler.js index cc792adab5..ae3ccafadb 100644 --- a/js/src/dom/eventHandler.js +++ b/js/src/dom/eventHandler.js @@ -91,13 +91,27 @@ function bootstrapHandler(element, fn) { } } +function bootstrapDelegationHandler(selector, fn) { + return function (event) { + const domElements = document.querySelectorAll(selector) + for (let target = event.target; target && target !== this; target = target.parentNode) { + for (let i = domElements.length; i--;) { + if (domElements[i] === target) { + return fn.apply(target, [event]) + } + } + } + } +} + const EventHandler = { - on(element, originalTypeEvent, handler) { + on(element, originalTypeEvent, handler, delegationFn) { if (typeof originalTypeEvent !== 'string' || (typeof element === 'undefined' || element === null)) { return } + const delegation = typeof handler === 'string' // allow to get the native events from namespaced events ('click.bs.button' --> 'click') let typeEvent = originalTypeEvent.replace(stripNameRegex, '') const isNative = nativeEvents.indexOf(typeEvent) > -1 @@ -107,12 +121,11 @@ const EventHandler = { const events = getEvent(element) const handlers = events[typeEvent] || (events[typeEvent] = {}) const uid = getUidEvent(handler, originalTypeEvent.replace(namespaceRegex, '')) - // TODO : Handle multi events on one element if (handlers[uid]) { return } - const fn = bootstrapHandler(element, handler) + const fn = !delegation ? bootstrapHandler(element, handler) : bootstrapDelegationHandler(handler, delegationFn) handlers[uid] = fn handler.uidEvent = uid element.addEventListener(typeEvent, fn, false) @@ -125,10 +138,8 @@ const EventHandler = { if (!events || !events[typeEvent]) { return } - const uidEvent = handler.uidEvent - const fn = events[typeEvent][uidEvent] - fn.apply(element, [e]) - EventHandler.off(element, event, handler) + handler.apply(element, [e]) + EventHandler.off(element, event, complete) } EventHandler.on(element, event, complete) }, -- 2.47.2