PageSourceSearch

https://www.revau.com/wp-content/plugins/Plugin_revau/blocks/stick…/sticky-nav-anchor.js?ver=0bb93de1b921

js revau.com collected 2026-10-06 19:56:41 UTC 4,209 bytes, 154 lines download raw bytes

1const ModuleStickyNavAnchor = {
2  _: {
3    initialize: false,
4    stickyNav: null,
5    footer: null,
6    anchors: [],
7    scrollTimeout: null,
8    lastFooterState: null,
9    verticalOffset: 0.4, // Facteur d'ajustement pour le centrage vertical (0.5 = 50%)
10  },
11
12  init() {
13    document.addEventListener("DOMContentLoaded", () => {
14      this.tryInit();
15    });
16
17    document.addEventListener("load", () => {
18      this.tryInit();
19    });
20
21    setTimeout(() => {
22      this.tryInit();
23    }, 100);
24  },
25
26  tryInit() {
27    if (this._.initialize) return;
28
29    this._.stickyNav = document.querySelector(".acf-block-sticky-nav-anchor");
30    this._.footer =
31      document.querySelector(".wp-site-blocks > footer") ||
32      document.querySelector("#colophon") ||
33      document.querySelector("footer");
34
35    if (!this._.stickyNav || !this._.footer) return;
36
37    this.collectAnchors();
38    if (this._.anchors.length === 0) return;
39
40    this.bindEvents();
41    this._.initialize = true;
42  },
43
44  collectAnchors() {
45    const navLinks = this._.stickyNav.querySelectorAll(
46      ".sticky-nav-anchor__link"
47    );
48
49    navLinks.forEach((link) => {
50      const anchorId = link.getAttribute("data-anchor");
51      if (anchorId) {
52        const anchorElement = document.getElementById(anchorId);
53        if (anchorElement) {
54          this._.anchors.push({
55            id: anchorId,
56            element: anchorElement,
57            link: link,
58          });
59        }
60      }
61    });
62  },
63
64  bindEvents() {
65    window.addEventListener("scroll", () => this.onScroll(), { passive: true });
66    window.addEventListener("resize", () => this.onScroll(), { passive: true });
67
68    this._.anchors.forEach(({ link, id }) => {
69      link.addEventListener("click", (e) => this.handleAnchorClick(e, id));
70    });
71
72    // Vérification initiale
73    setTimeout(() => {
74      this.checkActiveAnchors();
75      this.checkFooterVisibility();
76    }, 300);
77  },
78
79  checkActiveAnchors() {
80    const scrollTop = window.scrollY;
81    const viewportHeight = window.innerHeight;
82    const triggerPoint = scrollTop + viewportHeight / 2;
83
84    let activeAnchor = null;
85
86    for (const anchor of this._.anchors) {
87      const rect = anchor.element.getBoundingClientRect();
88      const elementTopDoc = rect.top + scrollTop;
89
90      if (elementTopDoc <= triggerPoint) {
91        activeAnchor = anchor;
92      }
93    }
94
95    this._.anchors.forEach(({ link }) => link.classList.remove("active"));
96
97    if (activeAnchor) {
98      activeAnchor.link.classList.add("active");
99    }
100  },
101
102  checkFooterVisibility() {
103    const footerRect = this._.footer.getBoundingClientRect();
104    const viewportHeight = window.innerHeight;
105    const footerTop = footerRect.top;
106    const threshold = 150;
107    const shouldHide = footerTop - viewportHeight < threshold;
108
109    if (shouldHide) {
110      if (!this._.stickyNav.classList.contains("hide")) {
111        this._.stickyNav.classList.add("hide");
112      }
113    } else {
114      if (this._.stickyNav.classList.contains("hide")) {
115        this._.stickyNav.classList.remove("hide");
116      }
117    }
118  },
119
120  onScroll() {
121    if (this._.scrollTimeout) {
122      window.cancelAnimationFrame(this._.scrollTimeout);
123    }
124
125    this._.scrollTimeout = window.requestAnimationFrame(() => {
126      this.checkActiveAnchors();
127      this.checkFooterVisibility();
128    });
129  },
130
131  handleAnchorClick(e, anchorId) {
132    e.preventDefault();
133    const targetElement = document.getElementById(anchorId);
134
135    if (targetElement) {
136      const viewportHeight = window.innerHeight;
137      const elementRect = targetElement.getBoundingClientRect();
138      const elementHeight = elementRect.height;
139
140      // Calcul pour centrer l'élément dans la fenêtre avec facteur d'ajustement
141      const targetPosition = window.scrollY + elementRect.top;
142      const centerOffset =
143        (viewportHeight - elementHeight) * this._.verticalOffset;
144      const offsetTop = targetPosition - 140;
145
146      window.scrollTo({
147        top: offsetTop,
148        behavior: "smooth",
149      });
150    }
151  },
152};
153
154ModuleStickyNavAnchor.init();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.