From 4a5029ea29ac75243dfec68153051292fc70f5cf Mon Sep 17 00:00:00 2001 From: alpadev <2838324+alpadev@users.noreply.github.com> Date: Thu, 3 Jun 2021 13:44:16 +0200 Subject: Fix handling of transitionend events dispatched by nested elements(#33845) Fix handling of transitionend events dispatched by nested elements Properly handle events from nested elements Change `emulateTransitionEnd` to `executeAfterTransition` && --- js/src/util/backdrop.js | 11 ++--------- js/src/util/index.js | 51 ++++++++++++++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 29 deletions(-) (limited to 'js/src/util') diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 07ad20fab7..028325d118 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -6,7 +6,7 @@ */ import EventHandler from '../dom/event-handler' -import { emulateTransitionEnd, execute, getElement, getTransitionDurationFromElement, reflow, typeCheckConfig } from './index' +import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index' const Default = { isVisible: true, // if false, we use the backdrop helper without adding any element to the dom @@ -122,14 +122,7 @@ class Backdrop { } _emulateAnimation(callback) { - if (!this._config.isAnimated) { - execute(callback) - return - } - - const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement()) - EventHandler.one(this._getElement(), 'transitionend', () => execute(callback)) - emulateTransitionEnd(this._getElement(), backdropTransitionDuration) + executeAfterTransition(callback, this._getElement(), this._config.isAnimated) } } diff --git a/js/src/util/index.js b/js/src/util/index.js index 4d077b21f9..6edfaa580d 100644 --- a/js/src/util/index.js +++ b/js/src/util/index.js @@ -126,24 +126,6 @@ const getElement = obj => { return null } -const emulateTransitionEnd = (element, duration) => { - let called = false - const durationPadding = 5 - const emulatedDuration = duration + durationPadding - - function listener() { - called = true - element.removeEventListener(TRANSITION_END, listener) - } - - element.addEventListener(TRANSITION_END, listener) - setTimeout(() => { - if (!called) { - triggerTransitionEnd(element) - } - }, emulatedDuration) -} - const typeCheckConfig = (componentName, config, configTypes) => { Object.keys(configTypes).forEach(property => { const expectedTypes = configTypes[property] @@ -252,6 +234,35 @@ const execute = callback => { } } +const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { + if (!waitForTransition) { + execute(callback) + return + } + + const durationPadding = 5 + const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding + + let called = false + + const handler = ({ target }) => { + if (target !== transitionElement) { + return + } + + called = true + transitionElement.removeEventListener(TRANSITION_END, handler) + execute(callback) + } + + transitionElement.addEventListener(TRANSITION_END, handler) + setTimeout(() => { + if (!called) { + triggerTransitionEnd(transitionElement) + } + }, emulatedDuration) +} + /** * Return the previous/next element of a list. * @@ -288,7 +299,6 @@ export { getTransitionDurationFromElement, triggerTransitionEnd, isElement, - emulateTransitionEnd, typeCheckConfig, isVisible, isDisabled, @@ -300,5 +310,6 @@ export { onDOMContentLoaded, isRTL, defineJQueryPlugin, - execute + execute, + executeAfterTransition } -- cgit v1.2.3