Site personnel courcellematthi.eu
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* back-to-top.js — Bouton de retour en haut de page
|
||||
* =============================================================================
|
||||
* Le bouton n'apparaît qu'une fois l'utilisateur descendu au-delà d'une
|
||||
* hauteur d'écran : afficher un raccourci de retour alors qu'on est déjà
|
||||
* en haut n'a aucune utilité et encombre l'interface.
|
||||
*
|
||||
* Détection par IntersectionObserver sur une sentinelle placée en haut du
|
||||
* document, plutôt que par écouteur de scroll — même raison que pour le
|
||||
* scroll-spy : pas de recalcul de mise en page à chaque pixel parcouru.
|
||||
*
|
||||
* Le bouton est un vrai <button> injecté par ce script : il n'a aucun sens
|
||||
* sans JavaScript, il ne doit donc pas exister dans le HTML servi.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise le bouton de retour en haut.
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {HTMLElement} options.button - Bouton à piloter.
|
||||
* @param {HTMLElement} options.sentinel - Élément repère en haut de page.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function initBackToTop({ button, sentinel }) {
|
||||
if (!button || !sentinel) return;
|
||||
|
||||
/* --- Action : remonter en haut -------------------------------------- */
|
||||
button.addEventListener("click", () => {
|
||||
// Respecte la préférence système de réduction des animations :
|
||||
// un défilement animé sur plusieurs milliers de pixels peut
|
||||
// provoquer un malaise chez les personnes photosensibles.
|
||||
const prefersReducedMotion = window.matchMedia(
|
||||
"(prefers-reduced-motion: reduce)"
|
||||
).matches;
|
||||
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: prefersReducedMotion ? "auto" : "smooth",
|
||||
});
|
||||
|
||||
// Le focus doit suivre le déplacement visuel, sinon un utilisateur
|
||||
// clavier se retrouve à naviguer depuis le bas de page.
|
||||
document.getElementById("haut-de-page")?.focus({ preventScroll: true });
|
||||
});
|
||||
|
||||
/* --- Visibilité conditionnelle -------------------------------------- */
|
||||
if (!("IntersectionObserver" in window)) return;
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
// La sentinelle est visible => on est en haut => bouton masqué.
|
||||
button.dataset.visible = String(!entry.isIntersecting);
|
||||
},
|
||||
{ threshold: 0 }
|
||||
);
|
||||
|
||||
observer.observe(sentinel);
|
||||
}
|
||||
Reference in New Issue
Block a user