From e3c23b50eed68e58f56b7b32ef7d6fc057f66b08 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Fri, 18 Sep 2020 12:31:43 +0000 Subject: [PATCH] [FIX] website, *: make scroll to anchor consider the fixed header *: website_blog This was fixed and rebroken quite a few times. Hopefully, with this commit and the next ones, the feature will be more robust: when clicking on a link anchor, the animation now considers the fixed header height if any *even if the header becomes fixed during the animation*. Part of https://github.com/odoo/odoo/pull/57975 task-2344227 X-original-commit: 416b125803d043badef8e4b022c100e33d1dba04 --- .../src/js/content/snippets.animation.js | 28 +++++++++++++++---- .../static/src/js/website_blog.js | 12 ++------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index 2840bc1e7e3..81640cde197 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -899,12 +899,28 @@ registry.anchorSlide = publicWidget.Widget.extend({ * @param {jQuery} $el the element to scroll to. * @param {string} [scrollValue='true'] scroll value */ - _scrollTo: function ($el, scrollValue = 'true') { - const headerHeight = this._computeHeaderHeight(); - const offset = $el.css('position') !== 'fixed' ? $el.offset().top : $el.position().top; - $('html, body').animate({ - scrollTop: offset - headerHeight, - }, scrollValue === 'true' ? 500 : 0); + _scrollTo: function ($el, scrollValue = 'true', forcedDelay = undefined) { + const _computeScrollTo = () => { + const headerHeight = this._computeHeaderHeight(); + const offset = $el.css('position') !== 'fixed' ? $el.offset().top : $el.position().top; + return offset - headerHeight; + }; + const originalScrollTo = _computeScrollTo(); + return new Promise(resolve => { + $('html, body').animate({ + scrollTop: originalScrollTo, + }, { + duration: forcedDelay || (scrollValue === 'true' ? 500 : 0), + progress: (a, b, remainingMs) => { + const scrollTo = _computeScrollTo(); + if (Math.abs(scrollTo - originalScrollTo) >= 1.0) { + $('html, body').stop(); + this._scrollTo($el, scrollValue, remainingMs).then(() => resolve()); + } + }, + complete: () => resolve(), + }); + }); }, /** * @private diff --git a/addons/website_blog/static/src/js/website_blog.js b/addons/website_blog/static/src/js/website_blog.js index d91460f16a4..3dfeb6b2f3d 100644 --- a/addons/website_blog/static/src/js/website_blog.js +++ b/addons/website_blog/static/src/js/website_blog.js @@ -2,8 +2,9 @@ odoo.define('website_blog.website_blog', function (require) { 'use strict'; var publicWidget = require('web.public.widget'); +require('website.content.snippets.animation'); -publicWidget.registry.websiteBlog = publicWidget.Widget.extend({ +publicWidget.registry.websiteBlog = publicWidget.registry.anchorSlide.extend({ selector: '.website_blog', events: { 'click #o_wblog_next_container': '_onNextBlogClick', @@ -92,14 +93,7 @@ publicWidget.registry.websiteBlog = publicWidget.Widget.extend({ * @param {Function} callback - to be executed after the scroll is performed */ _forumScrollAction: function ($el, duration, callback) { - const $main = $('#wrapwrap > main'); - var gap = $main.offset().top + parseInt($main.css('padding-top')); - - $('html, body').stop().animate({ - scrollTop: $el.offset().top - gap - }, duration, 'swing', function () { - callback(); - }); + this._scrollTo($el, 'true', duration).then(() => callback()); }, }); });