Permalink
Browse files

feat(carousel): Transition event with setTimeout fallback

  • Loading branch information...
tmorehouse committed Aug 13, 2017
1 parent 6746cb1 commit 8e6fc42f0829c5ca0d17f207270f8984ee8cbb05
Showing with 36 additions and 15 deletions.
  1. +36 −15 lib/components/carousel.vue
@@ -90,6 +90,9 @@
overlayClass: 'carousel-item-prev'
}
};
// Fallback Transition duration (with a little buffer) in ms
const TRANS_DURATION = 600 + 50;
// Transition Event names
const TransitionEndEvents = {
@@ -107,7 +110,7 @@
}
}
// fallback
return 'transitionend';
return null;
}
export default {
@@ -116,7 +119,7 @@
index: this.value || 0,
isSliding: false,
intervalId: null,
transitionEndEvent: 'transitionend',
transitionEndEvent: null,
slides: []
};
},
@@ -229,7 +232,7 @@
});
this.intervalId = setInterval(() => {
this.next();
}, this.interval);
}, Math.min(1000, this.interval));
},
// Re-Start auto rotate slides when focus/hover leaves the carousel
@@ -272,16 +275,6 @@
}
},
mounted() {
// Cache current browser transitionend event name
this.transitionEndEvent = getTransisionEndEvent(this.$el);
// Get all slides
this.updateSlides();
// Observe child changes so we can update slide list
observeDom(this.$refs.inner, this.updateSlides.bind(this), {subtree: false});
},
watch: {
value(newVal, oldVal) {
if (newVal !== oldVal) {
@@ -341,8 +334,16 @@
nextSlide.classList.add(direction.dirClass);
// Transition End handler
let called = false;
const onceTransEnd = (evt) => {
currentSlide.removeEventListener(this.transitionEndEvent, onceTransEnd);
if (called) {
return;
}
called = true;
if (this.transitionEndEvent) {
currentSlide.removeEventListener(this.transitionEndEvent, onceTransEnd);
}
this._animationTimeout = null;
nextSlide.classList.remove(direction.dirClass);
nextSlide.classList.remove(direction.overlayClass);
@@ -374,11 +375,31 @@
};
// Clear transition classes after transition ends
currentSlide.addEventListener(this.transitionEndEvent, onceTransEnd);
if (this.transitionEndEvent) {
currentSlide.addEventListener(this.transitionEndEvent, onceTransEnd);
}
// Fallback to setTimeout
this._animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION);
}
},
created() {
// Create private non-reactive props
this._animationTimeout = null;
},
mounted() {
// Cache current browser transitionend event name
this.transitionEndEvent = getTransisionEndEvent(this.$el) || null;
// Get all slides
this.updateSlides();
// Observe child changes so we can update slide list
observeDom(this.$refs.inner, this.updateSlides.bind(this), {subtree: false});
},
destroyed() {
clearInterval(this.intervalId);
clearTimeout(this._animationTimeout);
this._animationTimeout = null;
}
};

0 comments on commit 8e6fc42

Please sign in to comment.