diff --git a/js/src/alert.js b/js/src/alert.js
index 64e8e38435..ab36a8d363 100644
--- a/js/src/alert.js
+++ b/js/src/alert.js
@@ -112,7 +112,8 @@ class Alert {
$(element)
.one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))
- .emulateTransitionEnd(transitionDuration)
+
+ Util.emulateTransitionEnd(transitionDuration)
}
_destroyElement(element) {
diff --git a/js/src/carousel.js b/js/src/carousel.js
index 36176dd9c0..fa0ce331a1 100644
--- a/js/src/carousel.js
+++ b/js/src/carousel.js
@@ -488,7 +488,8 @@ class Carousel {
setTimeout(() => $(this._element).trigger(slidEvent), 0)
})
- .emulateTransitionEnd(transitionDuration)
+
+ Util.emulateTransitionEnd(transitionDuration)
} else {
$(activeElement).removeClass(ClassName.ACTIVE)
$(nextElement).addClass(ClassName.ACTIVE)
diff --git a/js/src/collapse.js b/js/src/collapse.js
index 10df450d09..a6b540de9e 100644
--- a/js/src/collapse.js
+++ b/js/src/collapse.js
@@ -195,8 +195,8 @@ class Collapse {
$(this._element)
.one(Util.TRANSITION_END, complete)
- .emulateTransitionEnd(transitionDuration)
+ Util.emulateTransitionEnd(transitionDuration)
this._element.style[dimension] = `${this._element[scrollSize]}px`
}
@@ -254,7 +254,8 @@ class Collapse {
$(this._element)
.one(Util.TRANSITION_END, complete)
- .emulateTransitionEnd(transitionDuration)
+
+ Util.emulateTransitionEnd(transitionDuration)
}
setTransitioning(isTransitioning) {
diff --git a/js/src/dom/event.js b/js/src/dom/event.js
new file mode 100644
index 0000000000..5968e62e0f
--- /dev/null
+++ b/js/src/dom/event.js
@@ -0,0 +1,38 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta): dom/event.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Event = {
+ on(element, event, handler) {
+ if (typeof event !== 'string') {
+ return
+ }
+ element.addEventListener(event, handler, false)
+ },
+
+ one(element, event, handler) {
+ const complete = () => {
+ /* eslint func-style: off */
+ handler()
+ element.removeEventListener(event, complete, false)
+ }
+ Event.on(element, event, complete)
+ },
+
+ trigger(element, event) {
+ if (typeof event !== 'string') {
+ return
+ }
+
+ const eventToDispatch = new CustomEvent(event, {
+ bubbles: true,
+ cancelable: true
+ })
+ element.dispatchEvent(eventToDispatch)
+ }
+}
+
+export default Event
diff --git a/js/src/modal.js b/js/src/modal.js
index 99fe1bf2d0..0668907ecb 100644
--- a/js/src/modal.js
+++ b/js/src/modal.js
@@ -189,7 +189,8 @@ class Modal {
$(this._element)
.one(Util.TRANSITION_END, (event) => this._hideModal(event))
- .emulateTransitionEnd(transitionDuration)
+
+ Util.emulateTransitionEnd(this._element, transitionDuration)
} else {
this._hideModal()
}
@@ -280,7 +281,8 @@ class Modal {
$(this._dialog)
.one(Util.TRANSITION_END, transitionComplete)
- .emulateTransitionEnd(transitionDuration)
+
+ Util.emulateTransitionEnd(transitionDuration)
} else {
transitionComplete()
}
@@ -387,7 +389,8 @@ class Modal {
$(this._backdrop)
.one(Util.TRANSITION_END, callback)
- .emulateTransitionEnd(backdropTransitionDuration)
+
+ Util.emulateTransitionEnd(backdropTransitionDuration)
} else if (!this._isShown && this._backdrop) {
$(this._backdrop).removeClass(ClassName.SHOW)
@@ -403,7 +406,8 @@ class Modal {
$(this._backdrop)
.one(Util.TRANSITION_END, callbackRemove)
- .emulateTransitionEnd(backdropTransitionDuration)
+
+ Util.emulateTransitionEnd(backdropTransitionDuration)
} else {
callbackRemove()
}
diff --git a/js/src/tab.js b/js/src/tab.js
index 8421e0a43c..cb80997afc 100644
--- a/js/src/tab.js
+++ b/js/src/tab.js
@@ -159,7 +159,7 @@ class Tab {
$(active)
.removeClass(ClassName.SHOW)
.one(Util.TRANSITION_END, complete)
- .emulateTransitionEnd(transitionDuration)
+ Util.emulateTransitionEnd(active, transitionDuration)
} else {
complete()
}
diff --git a/js/src/tooltip.js b/js/src/tooltip.js
index 81a2dedc6c..64dcb08401 100644
--- a/js/src/tooltip.js
+++ b/js/src/tooltip.js
@@ -344,7 +344,8 @@ class Tooltip {
$(this.tip)
.one(Util.TRANSITION_END, complete)
- .emulateTransitionEnd(transitionDuration)
+
+ Util.emulateTransitionEnd(tip, transitionDuration)
} else {
complete()
}
diff --git a/js/src/util.js b/js/src/util.js
index d459aa266b..989d9644fc 100644
--- a/js/src/util.js
+++ b/js/src/util.js
@@ -5,7 +5,7 @@
* --------------------------------------------------------------------------
*/
-import $ from 'jquery'
+import Event from './dom/event'
/**
* ------------------------------------------------------------------------
@@ -118,7 +118,7 @@ const Util = {
},
triggerTransitionEnd(element) {
- $(element).trigger(TRANSITION_END)
+ Event.trigger(element, Util.TRANSITION_END)
},
// TODO: Remove in v5
@@ -130,6 +130,12 @@ const Util = {
return (obj[0] || obj).nodeType
},
+ emulateTransitionEnd(element, duration) {
+ setTimeout(() => {
+ Util.triggerTransitionEnd(element)
+ }, duration)
+ },
+
typeCheckConfig(componentName, config, configTypes) {
for (const property in configTypes) {
if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
@@ -172,6 +178,4 @@ const Util = {
}
}
-setTransitionEndSupport()
-
export default Util
diff --git a/js/tests/index.html b/js/tests/index.html
index 99acd4ad4e..a3fd937c2d 100644
--- a/js/tests/index.html
+++ b/js/tests/index.html
@@ -97,6 +97,7 @@
+
diff --git a/js/tests/visual/alert.html b/js/tests/visual/alert.html
index 6eb7e9444c..d2befb8b8a 100644
--- a/js/tests/visual/alert.html
+++ b/js/tests/visual/alert.html
@@ -52,6 +52,7 @@
+