diff --git a/js/src/alert.js b/js/src/alert.js index 884041580c..8d0838737a 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -7,9 +7,7 @@ import { defineJQueryPlugin, - emulateTransitionEnd, - getElementFromSelector, - getTransitionDurationFromElement + getElementFromSelector } from './util/index' import Data from './dom/data' import EventHandler from './dom/event-handler' @@ -75,15 +73,8 @@ class Alert extends BaseComponent { _removeElement(element) { element.classList.remove(CLASS_NAME_SHOW) - if (!element.classList.contains(CLASS_NAME_FADE)) { - this._destroyElement(element) - return - } - - const transitionDuration = getTransitionDurationFromElement(element) - - EventHandler.one(element, 'transitionend', () => this._destroyElement(element)) - emulateTransitionEnd(element, transitionDuration) + const isAnimated = element.classList.contains(CLASS_NAME_FADE) + this._queueCallback(() => this._destroyElement(element), element, isAnimated) } _destroyElement(element) { diff --git a/js/src/base-component.js b/js/src/base-component.js index a0bb62319e..7d2a5b1e87 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -6,6 +6,11 @@ */ import Data from './dom/data' +import { + emulateTransitionEnd, + execute, + getTransitionDurationFromElement +} from './util/index' import EventHandler from './dom/event-handler' /** @@ -34,6 +39,18 @@ class BaseComponent { this._element = null } + _queueCallback(callback, element, isAnimated = true) { + if (!isAnimated) { + execute(callback) + return + } + + const transitionDuration = getTransitionDurationFromElement(element) + EventHandler.one(element, 'transitionend', () => execute(callback)) + + emulateTransitionEnd(element, transitionDuration) + } + /** Static */ static getInstance(element) { diff --git a/js/src/carousel.js b/js/src/carousel.js index 5bf7225f3c..2f5cd9de95 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -7,9 +7,7 @@ import { defineJQueryPlugin, - emulateTransitionEnd, getElementFromSelector, - getTransitionDurationFromElement, isRTL, isVisible, reflow, @@ -454,6 +452,15 @@ class Carousel extends BaseComponent { this._setActiveIndicatorElement(nextElement) this._activeElement = nextElement + const triggerSlidEvent = () => { + EventHandler.trigger(this._element, EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }) + } + if (this._element.classList.contains(CLASS_NAME_SLIDE)) { nextElement.classList.add(orderClassName) @@ -462,9 +469,7 @@ class Carousel extends BaseComponent { activeElement.classList.add(directionalClassName) nextElement.classList.add(directionalClassName) - const transitionDuration = getTransitionDurationFromElement(activeElement) - - EventHandler.one(activeElement, 'transitionend', () => { + const completeCallBack = () => { nextElement.classList.remove(directionalClassName, orderClassName) nextElement.classList.add(CLASS_NAME_ACTIVE) @@ -472,28 +477,16 @@ class Carousel extends BaseComponent { this._isSliding = false - setTimeout(() => { - EventHandler.trigger(this._element, EVENT_SLID, { - relatedTarget: nextElement, - direction: eventDirectionName, - from: activeElementIndex, - to: nextElementIndex - }) - }, 0) - }) + setTimeout(triggerSlidEvent, 0) + } - emulateTransitionEnd(activeElement, transitionDuration) + this._queueCallback(completeCallBack, activeElement, true) } else { activeElement.classList.remove(CLASS_NAME_ACTIVE) nextElement.classList.add(CLASS_NAME_ACTIVE) this._isSliding = false - EventHandler.trigger(this._element, EVENT_SLID, { - relatedTarget: nextElement, - direction: eventDirectionName, - from: activeElementIndex, - to: nextElementIndex - }) + triggerSlidEvent() } if (isCycling) { diff --git a/js/src/collapse.js b/js/src/collapse.js index 947b6e6585..bd3846e053 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -7,10 +7,8 @@ import { defineJQueryPlugin, - emulateTransitionEnd, getSelectorFromElement, getElementFromSelector, - getTransitionDurationFromElement, isElement, reflow, typeCheckConfig @@ -200,11 +198,8 @@ class Collapse extends BaseComponent { const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1) const scrollSize = `scroll${capitalizedDimension}` - const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) - - emulateTransitionEnd(this._element, transitionDuration) + this._queueCallback(complete, this._element, true) this._element.style[dimension] = `${this._element[scrollSize]}px` } @@ -250,10 +245,8 @@ class Collapse extends BaseComponent { } this._element.style[dimension] = '' - const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) - emulateTransitionEnd(this._element, transitionDuration) + this._queueCallback(complete, this._element, true) } setTransitioning(isTransitioning) { diff --git a/js/src/modal.js b/js/src/modal.js index 773e4263fd..6701c896f7 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -176,14 +176,7 @@ class Modal extends BaseComponent { EventHandler.off(this._element, EVENT_CLICK_DISMISS) EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS) - if (isAnimated) { - const transitionDuration = getTransitionDurationFromElement(this._element) - - EventHandler.one(this._element, 'transitionend', event => this._hideModal(event)) - emulateTransitionEnd(this._element, transitionDuration) - } else { - this._hideModal() - } + this._queueCallback(() => this._hideModal(), this._element, isAnimated) } dispose() { @@ -271,14 +264,7 @@ class Modal extends BaseComponent { }) } - if (isAnimated) { - const transitionDuration = getTransitionDurationFromElement(this._dialog) - - EventHandler.one(this._dialog, 'transitionend', transitionComplete) - emulateTransitionEnd(this._dialog, transitionDuration) - } else { - transitionComplete() - } + this._queueCallback(transitionComplete, this._dialog, isAnimated) } _enforceFocus() { diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index f3459e667b..68f8e81422 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -7,9 +7,7 @@ import { defineJQueryPlugin, - emulateTransitionEnd, getElementFromSelector, - getTransitionDurationFromElement, isDisabled, isVisible, typeCheckConfig @@ -124,9 +122,7 @@ class Offcanvas extends BaseComponent { EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget }) } - const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', completeCallBack) - emulateTransitionEnd(this._element, transitionDuration) + this._queueCallback(completeCallBack, this._element, true) } hide() { @@ -159,9 +155,7 @@ class Offcanvas extends BaseComponent { EventHandler.trigger(this._element, EVENT_HIDDEN) } - const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', completeCallback) - emulateTransitionEnd(this._element, transitionDuration) + this._queueCallback(completeCallback, this._element, true) } dispose() { diff --git a/js/src/tab.js b/js/src/tab.js index 73eb5a8202..8ee2738113 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -7,9 +7,7 @@ import { defineJQueryPlugin, - emulateTransitionEnd, getElementFromSelector, - getTransitionDurationFromElement, isDisabled, reflow } from './util/index' @@ -125,11 +123,8 @@ class Tab extends BaseComponent { const complete = () => this._transitionComplete(element, active, callback) if (active && isTransitioning) { - const transitionDuration = getTransitionDurationFromElement(active) active.classList.remove(CLASS_NAME_SHOW) - - EventHandler.one(active, 'transitionend', complete) - emulateTransitionEnd(active, transitionDuration) + this._queueCallback(complete, element, true) } else { complete() } diff --git a/js/src/toast.js b/js/src/toast.js index 364de29b42..c8539b3a96 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -7,8 +7,6 @@ import { defineJQueryPlugin, - emulateTransitionEnd, - getTransitionDurationFromElement, reflow, typeCheckConfig } from './util/index' @@ -112,14 +110,8 @@ class Toast extends BaseComponent { this._element.classList.remove(CLASS_NAME_HIDE) reflow(this._element) this._element.classList.add(CLASS_NAME_SHOWING) - if (this._config.animation) { - const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) - emulateTransitionEnd(this._element, transitionDuration) - } else { - complete() - } + this._queueCallback(complete, this._element, this._config.animation) } hide() { @@ -139,14 +131,7 @@ class Toast extends BaseComponent { } this._element.classList.remove(CLASS_NAME_SHOW) - if (this._config.animation) { - const transitionDuration = getTransitionDurationFromElement(this._element) - - EventHandler.one(this._element, 'transitionend', complete) - emulateTransitionEnd(this._element, transitionDuration) - } else { - complete() - } + this._queueCallback(complete, this._element, this._config.animation) } dispose() { diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 37ef8cb89d..65eb7a11ca 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -9,9 +9,7 @@ import * as Popper from '@popperjs/core' import { defineJQueryPlugin, - emulateTransitionEnd, findShadowRoot, - getTransitionDurationFromElement, getUID, isElement, isRTL, @@ -315,13 +313,8 @@ class Tooltip extends BaseComponent { } } - if (this.tip.classList.contains(CLASS_NAME_FADE)) { - const transitionDuration = getTransitionDurationFromElement(this.tip) - EventHandler.one(this.tip, 'transitionend', complete) - emulateTransitionEnd(this.tip, transitionDuration) - } else { - complete() - } + const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE) + this._queueCallback(complete, this.tip, isAnimated) } hide() { @@ -367,15 +360,8 @@ class Tooltip extends BaseComponent { this._activeTrigger[TRIGGER_FOCUS] = false this._activeTrigger[TRIGGER_HOVER] = false - if (this.tip.classList.contains(CLASS_NAME_FADE)) { - const transitionDuration = getTransitionDurationFromElement(tip) - - EventHandler.one(tip, 'transitionend', complete) - emulateTransitionEnd(tip, transitionDuration) - } else { - complete() - } - + const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE) + this._queueCallback(complete, this.tip, isAnimated) this._hoverState = '' }