PageSourceSearch

https://www.indragroup.com/static/v1.0.519-34fc345/blocks-js/HeaderVisibility.js

js indragroup.com collected 2026-09-24 17:39:33 UTC 4,534 bytes, 150 lines download raw bytes

1function HeaderVisibility() {
2  const state = {
3    isOverHero: false,
4    isScrollingDown: true,
5  }
6
7  let navigationMenu = null
8  let globalMenu = null
9
10  let heroElem = null
11  let pageContent = null
12
13  // setScrollDirectionClass > Añade clases al body según la dirección del scroll
14  // -------------------------------------------------------------------------
15  const setScrollDirectionClass = () => {
16    let lastScrollTop = window.scrollY || document.documentElement.scrollTop
17    let isScrollListenerActive = false
18
19    window.addEventListener('scrollend', (e) => {
20      // si se hace scroll to top muy rápido no se ponía transparent
21      updateHeaderTransparency()
22      updateHeaderPosition()
23    })
24
25    window.addEventListener('scroll', () => {
26      const currentScrollTop =
27        window.scrollY || document.documentElement.scrollTop
28
29      const isScrollingDown = currentScrollTop > lastScrollTop
30
31      // Avoid negative scroll values
32      lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop
33
34      if (isScrollListenerActive) {
35        return
36      }
37
38      isScrollListenerActive = true
39
40      state.isScrollingDown = isScrollingDown
41
42      if (isScrollingDown) {
43        // Scrolling down
44        document.body.classList.remove('scrolling-up')
45        document.body.classList.add('scrolling-down')
46      } else {
47        // Scrolling up
48        document.body.classList.remove('scrolling-down')
49        document.body.classList.add('scrolling-up')
50      }
51
52      updateHeaderTransparency()
53      updateHeaderPosition()
54
55      setTimeout(() => {
56        isScrollListenerActive = false
57      }, 0) // tiempo de animación del header
58    })
59  }
60
61  // setStickyObserver > Observa si un elemento se vuelve sticky
62  // -------------------------------------------------------------------------
63  const setStickyObserver = (stickyElem, stickyClass) => {
64    if (!stickyElem) return
65
66    const observer = new IntersectionObserver(
67      ([entry]) => {
68        const isSticky = entry.intersectionRatio < 1
69        document.body.classList.toggle(stickyClass, isSticky)
70      },
71      { threshold: [1] },
72    )
73
74    observer.observe(stickyElem)
75  }
76
77  // observeHeroIntersection > Observa si el header está superpuesto con el hero
78  // -------------------------------------------------------------------------
79  const observeHeroIntersection = () => {
80    const headerHeight = navigationMenu.offsetHeight
81
82    const observer = new IntersectionObserver(
83      ([entry]) => {
84        state.isOverHero = entry.isIntersecting
85        pageContent.classList.toggle('is-over-hero', entry.isIntersecting)
86        updateHeaderTransparency()
87        updateHeaderPosition()
88      },
89      {
90        root: null,
91        threshold: 0,
92        rootMargin: `-${headerHeight}px 0px 0px 0px`, // empieza a contar justo debajo del header
93      },
94    )
95
96    observer.observe(heroElem)
97  }
98
99  const updateHeaderPosition = () => {
100    if (window.scrollY < 1) {
101      document.body.classList.remove('scrolling-down')
102      document.body.classList.add('scrolling-up')
103
104      document.body.classList.add('page-on-top')
105    } else {
106      document.body.classList.remove('page-on-top')
107    }
108  }
109
110  // Aplica o elimina la clase transparente
111  // -------------------------------------------------------------------------
112  const updateHeaderTransparency = () => {
113    if (!heroElem) return
114
115    const heroRect = heroElem.getBoundingClientRect()
116    const isAtTopOfHero = heroRect.top >= 0
117
118    let shouldBeTransparent
119    if (window.scrollY < 1) {
120      shouldBeTransparent = true
121    } else {
122      shouldBeTransparent =
123        state.isOverHero &&
124        (state.isScrollingDown || (!state.isScrollingDown && isAtTopOfHero))
125    }
126
127    pageContent.classList.toggle('has-header-transparent', shouldBeTransparent)
128  }
129
130  // setHeaderVisibility > Inicializa todos los observadores
131  // -------------------------------------------------------------------------
132  const init = () => {
133    navigationMenu = document.querySelector('[data-js="header-menu--page"]')
134    globalMenu = document.querySelector('[data-js="header-menu--global"]')
135
136    heroElem =
137      document.querySelector('.hero') || document.querySelector('.hero-video')
138    pageContent = document.querySelector('.page-content')
139
140    setStickyObserver(navigationMenu, 'is-navigation-sticky')
141    setStickyObserver(globalMenu, 'is-menu-global-sticky')
142
143    setScrollDirectionClass()
144    if (heroElem) observeHeroIntersection()
145  }
146
147  return { init }
148}
149
150HeaderVisibility().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.