[FIX] website: make anchor links work in offcanvas mobile menu

A anchor menu in the mobile offcanvas related to an element in the
current page doesn't work in offcanvas:
- The offcanvas doesn't close
- The page doesn't scroll to the clicked location

This is because the menu anchor navigation is hooked to use our own
scrolling behavior instead of the browser one.

Doing so, we preventDefault, which prevent the offcanvas menu to close
itself when clicking on a anchor menu.

This commit simply manually closes the offcanvas and once the closing
animation is complete, starts our own smooth scrolling.
It also targets the desktop offcanvas menu (when hamburger layout is
selected) so it got a smoother UX: it closes then scrolls, instead of
scrolling but not closing.

Another possibility would have been to just close manually the offcanvas
without a preventDefault and without a call to our custom scrolling
method.
Doing so, the browser would naturally scroll to the element while we
close the offcanvas but it would be less elegant as you wouldn't see the
scrolling animation.

Note that the offcanvas was introduced with commit [1].

[1]: https://github.com/odoo/odoo/commit/bc13176de8d66bbdc1c536017b1f046c5fd31a86

opw-3604963

closes odoo/odoo#146907

X-original-commit: db881e66785a866319bd4980a9ae7b6393e55457
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Romain Derie
2023-12-26 08:36:44 +00:00
parent 97333d421f
commit cb1ad42130
3 changed files with 19 additions and 2 deletions
+1
View File
@@ -60,6 +60,7 @@
"Collapse": "readonly",
"Dropdown": "readonly",
"Modal": "readonly",
"Offcanvas": "readonly",
"Popover": "readonly",
"Tooltip": "readonly"
}
@@ -1039,8 +1039,23 @@ registry.anchorSlide = publicWidget.Widget.extend({
if (!$anchor.length || !scrollValue) {
return;
}
ev.preventDefault();
this._scrollTo($anchor, scrollValue);
const offcanvasEl = this.el.closest('.offcanvas.o_navbar_mobile');
if (offcanvasEl && offcanvasEl.classList.contains('show')) {
// Special case for anchors in offcanvas in mobile: we can't just
// _scrollTo() after preventDefault because preventDefault would
// prevent the offcanvas to be closed. The choice is then to close
// it ourselves manually and once it's fully closed, then start our
// own smooth scrolling.
ev.preventDefault();
Offcanvas.getInstance(offcanvasEl).hide();
offcanvasEl.addEventListener('hidden.bs.offcanvas', () => {
this._scrollTo($anchor, scrollValue);
});
} else {
ev.preventDefault();
this._scrollTo($anchor, scrollValue);
}
},
});
+1
View File
@@ -46,6 +46,7 @@
"Collapse": "readonly",
"Dropdown": "readonly",
"Modal": "readonly",
"Offcanvas": "readonly",
"Popover": "readonly",
"Tooltip": "readonly"
}