transitionEnd helper
by Julien Etienne
HTML
<div id="box"></div>
CSS
#box {
width: 6.25rem;
height: 6.25rem;
background: red;
transition: all 250ms ease;
}
JavaScript
const transitionEndPartial = () => {
let once = true;
let defaultTransition;
let transitionEvent;
return (element, callback, transition) => {
console.log('transitionEnd')
const isElement = element instanceof Element;
if (!isElement) {
console.error(`transitionEnd: ${element} is not an element`);
}
if (once) {
console.log('once')
once = false;
defaultTransition = window.getComputedStyle(element).getPropertyValue('transition')
transitionEvent = new TransitionEvent('transitionend', {
view: window,
bubbles: true,
cancelable: true
});
}
return new Promise((resolve, reject) => {
const transitionResolver = () => {
console.log('transitionResolver');
element.removeEventListener('transitionend', transitionResolver, false);
const endOfTransition = () => {
element.removeEventListener('transitionend', endOfTransition, false);
resolve(element);
};
element.addEventListener('transitionend', endOfTransition, false);
callback(element);
}
element.addEventListener('transitionend', transitionResolver, false);
if (transition) {
element.style.transition = transition;
} else {
element.style.transition = defaultTransition;
}
element.dispatchEvent(transitionEvent);
});
}
}
const transitionEnd = transitionEndPartial();
/*
Demo code...
*/
const box = document.querySelector('#box');
const changeColor = (element, color) => element.style.background = color;
const makeBlue = element => changeColor(element, 'blue');
const makePink = element => changeColor(element, 'pink');
const makeLime = element => changeColor(element, 'lime');
const newHeight = height => box.style.height = height;
const newWidth = width => box.style.width = width;
/*
Declarative via async await
*/
const cycleColors = async () => {
await transitionEnd(box, makeLime);
await...