diff options
| author | Alessandro Chitolina <[email protected]> | 2017-09-15 16:07:24 +0200 |
|---|---|---|
| committer | XhmikosR <[email protected]> | 2019-02-20 22:05:45 +0200 |
| commit | 33211eefdfb27eff7ba21886e16f2efdc0efa3e6 (patch) | |
| tree | f8f3f3342a6c2c2363448346debf52beb4954b21 /js/src/dom/eventHandler.js | |
| parent | 9f9712b98c92678c709b2ad0adfa954e3c120911 (diff) | |
| download | bootstrap-33211eefdfb27eff7ba21886e16f2efdc0efa3e6.tar.xz bootstrap-33211eefdfb27eff7ba21886e16f2efdc0efa3e6.zip | |
Rewritten modal without jquery (#23955)
* Trigger jquery events if available in event handler
* Rewritten modal without jquery
Diffstat (limited to 'js/src/dom/eventHandler.js')
| -rw-r--r-- | js/src/dom/eventHandler.js | 105 |
1 files changed, 81 insertions, 24 deletions
diff --git a/js/src/dom/eventHandler.js b/js/src/dom/eventHandler.js index 746f84bcb..a69ab6136 100644 --- a/js/src/dom/eventHandler.js +++ b/js/src/dom/eventHandler.js @@ -63,6 +63,7 @@ if (!window.Event || typeof window.Event !== 'function') { const namespaceRegex = /[^.]*(?=\..*)\.|.*/ const stripNameRegex = /\..*/ const keyEventRegex = /^key/ +const stripUidRegex = /::\d+$/ // Events storage const eventRegistry = {} @@ -110,10 +111,10 @@ function bootstrapHandler(element, fn) { } } -function bootstrapDelegationHandler(selector, fn) { +function bootstrapDelegationHandler(element, selector, fn) { return function (event) { event = fixEvent(event) - const domElements = document.querySelectorAll(selector) + const domElements = element.querySelectorAll(selector) for (let target = event.target; target && target !== this; target = target.parentNode) { for (let i = domElements.length; i--;) { if (domElements[i] === target) { @@ -126,6 +127,26 @@ function bootstrapDelegationHandler(selector, fn) { } } +function removeHandler(element, events, typeEvent, handler) { + const uidEvent = handler.uidEvent + const fn = events[typeEvent][uidEvent] + element.removeEventListener(typeEvent, fn, fn.delegation) + delete events[typeEvent][uidEvent] +} + +function removeNamespacedHandlers(element, events, typeEvent, namespace) { + const storeElementEvent = events[typeEvent] || {} + for (const handlerKey in storeElementEvent) { + if (!Object.prototype.hasOwnProperty.call(storeElementEvent, handlerKey)) { + continue + } + + if (handlerKey.indexOf(namespace) > -1) { + removeHandler(element, events, typeEvent, storeElementEvent[handlerKey].originalHandler) + } + } +} + const EventHandler = { on(element, originalTypeEvent, handler, delegationFn) { if (typeof originalTypeEvent !== 'string' || @@ -155,7 +176,7 @@ const EventHandler = { return } - const fn = !delegation ? bootstrapHandler(element, handler) : bootstrapDelegationHandler(handler, delegationFn) + const fn = !delegation ? bootstrapHandler(element, handler) : bootstrapDelegationHandler(element, handler, delegationFn) fn.isDelegation = delegation handlers[uid] = fn originalHandler.uidEvent = uid @@ -179,43 +200,49 @@ const EventHandler = { const events = getEvent(element) let typeEvent = originalTypeEvent.replace(stripNameRegex, '') + const inNamespace = typeEvent !== originalTypeEvent const custom = customEvents[typeEvent] if (custom) { typeEvent = custom } + const isNative = nativeEvents.indexOf(typeEvent) > -1 if (!isNative) { typeEvent = originalTypeEvent } - if (typeof handler === 'undefined') { + if (typeof handler !== 'undefined') { + // Simplest case: handler is passed, remove that listener ONLY. + if (!events || !events[typeEvent]) { + return + } + + removeHandler(element, events, typeEvent, handler) + return + } + + const isNamespace = originalTypeEvent.charAt(0) === '.' + if (isNamespace) { for (const elementEvent in events) { if (!Object.prototype.hasOwnProperty.call(events, elementEvent)) { continue } - const storeElementEvent = events[elementEvent] - for (const keyHandlers in storeElementEvent) { - if (!Object.prototype.hasOwnProperty.call(storeElementEvent, keyHandlers)) { - continue - } - // delete all the namespaced listeners - if (inNamespace && keyHandlers.indexOf(originalTypeEvent) > -1) { - const handlerFn = events[elementEvent][keyHandlers] - EventHandler.off(element, elementEvent, handlerFn.originalHandler) - } - } + removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.substr(1)) } - } else { - if (!events || !events[typeEvent]) { - return + } + + const storeElementEvent = events[typeEvent] || {} + for (const keyHandlers in storeElementEvent) { + if (!Object.prototype.hasOwnProperty.call(storeElementEvent, keyHandlers)) { + continue } - const uidEvent = handler.uidEvent - const fn = events[typeEvent][uidEvent] - element.removeEventListener(typeEvent, fn, fn.delegation) - delete events[typeEvent][uidEvent] + const handlerKey = keyHandlers.replace(stripUidRegex, '') + if (!inNamespace || originalTypeEvent.indexOf(handlerKey) > -1) { + removeHandler(element, events, typeEvent, storeElementEvent[keyHandlers].originalHandler) + } } }, @@ -226,7 +253,25 @@ const EventHandler = { } const typeEvent = event.replace(stripNameRegex, '') + const inNamespace = event !== typeEvent const isNative = nativeEvents.indexOf(typeEvent) > -1 + + const $ = Util.jQuery + let jQueryEvent + + let bubbles = true + let nativeDispatch = true + let defaultPrevented = false + + if (inNamespace && typeof $ !== 'undefined') { + jQueryEvent = new $.Event(event, args) + + $(element).trigger(jQueryEvent) + bubbles = !jQueryEvent.isPropagationStopped() + nativeDispatch = !jQueryEvent.isImmediatePropagationStopped() + defaultPrevented = jQueryEvent.isDefaultPrevented() + } + let evt = null if (isNative) { @@ -234,7 +279,7 @@ const EventHandler = { evt.initEvent(typeEvent, true, true) } else { evt = new CustomEvent(event, { - bubbles: true, + bubbles, cancelable: true }) } @@ -243,7 +288,19 @@ const EventHandler = { if (typeof args !== 'undefined') { evt = Util.extend(evt, args) } - element.dispatchEvent(evt) + + if (defaultPrevented) { + evt.preventDefault() + } + + if (nativeDispatch) { + element.dispatchEvent(evt) + } + + if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') { + jQueryEvent.preventDefault() + } + return evt } } |
