In case someone comes across this, here's what I ended up doing (thanks, @Lynyrd!)
// transition names (found in Modernizr)
let transEndEventNames = {
'WebkitTransition': 'webkitTransitionEnd', // Saf 6, Android Browser
'MozTransition': 'transitionend', // only for FF < 15
'transition': 'transitionend', // IE10, Opera, Chrome, FF 15+, Saf 7+
};
I use React, so I added the event listeners in useEffect so that they automatically get added if the foodList is fetched again etc.
// add & remove event listeners for transition end
useEffect(() => {
foodList.forEach((item, index) => {
if (!document.getElementById(index)) return;
document
.getElementById(index)
.addEventListener(
transEndEventNames.WebkitTransition,
handleTransitionEnd
);
document
.getElementById(index)
.addEventListener(
transEndEventNames.MozTransition,
handleTransitionEnd
);
document
.getElementById(index)
.addEventListener(transEndEventNames.transition, handleTransitionEnd);
});
return () => {
foodList.forEach((item, index) => {
if (!document.getElementById(index)) return;
document
.getElementById(index)
.removeEventListener(
transEndEventNames.WebkitTransition,
handleTransitionEnd
);
document
.getElementById(index)
.removeEventListener(
transEndEventNames.MozTransition,
handleTransitionEnd
);
document
.getElementById(index)
.removeEventListener(
transEndEventNames.transition,
handleTransitionEnd
);
});
};
}, [foodList]);
I decided against trying to add only one event listener depending on the current browser, but that would be possible too.
Keep in mind, that this listener get's triggered for every transition. As a result, my table entries got deleted when somebody hovered over an element in (which triggered a tooltip). So don't forget to filter:
function handleTransitionEnd(event) {
// only delete element for transform transition
if (!(event.propertyName === 'transform')) return;
let newState = foodList.slice();
newState.splice(event.target.id, 1);
setFoodList(newState);
}
In my case, this is pretty easy, because I only have one "transform" transition on the element. Also, I have no idea if the amount of eventListeners become a performance problem for larger tables.
The setTimeout() function isn't needed at all now, in deleteFood() I now only start the animation and delete the item from my database:
function DeleteFood(index) {
// animate
document.getElementById(index).style.transform = 'translate(500px, 0)';
// delete from airtable
foodList[index].destroy();
}