[FIX] website: avoid flickering when switching slide in editor
Before this commit, when an user clicked on a control button to go to another carousel slide, the overlay ended at the wrong position and multiple scrollbars appeared. This occured because bootstrap fires the 'slid.bs.carousel' event too soon, because it emulates the transition end event with a setTimeout. So on a normal computer, this occured: - User click on control button, transition starts. - slid.bs.carousel is fired -> we retarget the edition to the new active slide and reposition the overlay... but that slide is still moving as the transition is not really finished. - The transition finishes, the overlay is at the wrong position, outside of the screen. Actually, this is more complex than than because our own system checks transition end events to reposition the overlay. Even if unperfect, we now have: - User click on control button, transition starts. - slide.bs.carousel is fired -> we enable the parent carousel instead of the current slide (this DOM element is not moving). - slid.bs.carousel is fired -> we know it is fired too soon, so we wait an extra 20% of the time between 'slide' and 'slid' before retargeting edition. - The transition finishes, the overlay is still over the carousel and not the active slide. - Our extra 20% duration ends, we retarget edition to the current slide and reposition the overlay (should not move since normally at the same position as the carousel itself). Part of https://github.com/odoo/odoo/pull/38997 task-2090180
This commit is contained in:
@@ -229,7 +229,20 @@ options.registry.carousel = options.Class.extend({
|
||||
this.$indicators = this.$target.find('.carousel-indicators');
|
||||
this.$controls = this.$target.find('.carousel-control-prev, .carousel-control-next, .carousel-indicators');
|
||||
this.$items = this.$target.find('.carousel-item');
|
||||
this.$target.on('slid.bs.carousel.carousel_option', () => this._retargetEdition());
|
||||
|
||||
let _slideTimestamp;
|
||||
this.$target.on('slide.bs.carousel.carousel_option', () => {
|
||||
_slideTimestamp = window.performance.now();
|
||||
setTimeout(() => this.trigger_up('activate_snippet', {$snippet: this.$target}));
|
||||
});
|
||||
this.$target.on('slid.bs.carousel.carousel_option', () => {
|
||||
// slid.bs.carousel is most of the time fired too soon by bootstrap
|
||||
// since it emulates the transitionEnd with a setTimeout. We wait
|
||||
// here an extra 20% of the time before retargeting edition, which
|
||||
// should be enough...
|
||||
const _slideDuration = (window.performance.now() - _slideTimestamp);
|
||||
setTimeout(() => this._retargetEdition(), 0.2 * _slideDuration);
|
||||
});
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
@@ -252,12 +265,6 @@ options.registry.carousel = options.Class.extend({
|
||||
onClone: function () {
|
||||
this._assignUniqueID();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
onFocus: function () {
|
||||
this._retargetEdition();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user