Script Correzione Scorrimento Menu

Script Correzione Scorrimento Menu

1. Calcola l’ingombro dell’Header

Quando clicchi su un link che punta a una sezione (es. #contatti), il browser di solito porta quella sezione in cima alla pagina. Se hai un menu fisso in alto, questo coprirà i primi pixel della sezione (spesso il titolo).

  • Cosa fa lo script: Calcola l’altezza del tuo header (#hdr) e sottrae quella misura dalla posizione finale dello scorrimento. In questo modo, la sezione si ferma esattamente sotto il menu.

2. Scorrimento Fluido (Smooth Scrolling)

Invece di un “salto” immediato e brusco alla sezione desiderata, lo script forza il browser a scivolare dolcemente verso il basso, migliorando l’esperienza utente.

3. Gestione dei Link Dinamici

Utilizza la “delegazione degli eventi” (document.addEventListener('click', ...)). Questo significa che lo script funziona anche su bottoni o link caricati in un secondo momento (es. tramite AJAX o widget dinamici) senza dover ricaricare lo script.

4. Risolve i problemi di caricamento di Elementor

I page builder come Elementor a volte impiegano qualche frazione di secondo per calcolare le altezze corrette della pagina.

  • La soluzione nel codice: Lo script contiene dei “delay” (ritardi di 60ms, 350ms e 500ms). Se un utente arriva sul sito tramite un link diretto a una sezione (es. tuosito.it/#servizi), lo script aspetta che la pagina sia pronta prima di scrollare, evitando che la posizione sia sbagliata.

5. Aggiorna l’URL senza ricaricare

Usa history.pushState. Quando clicchi su un link, l’indirizzo nella barra del browser si aggiorna (aggiungendo #sezione), ma senza causare lo sfarfallio o il salto tipico del comportamento standard del browser.


In sintesi, ti serve se:

  1. Hai un header fisso che copre i titoli delle sezioni quando ci clicchi sopra.
  2. Vuoi che lo scorrimento sia morbido ed elegante.
  3. Vuoi che i link funzionino bene anche se l’utente arriva sulla pagina da un link esterno che punta a un’ancora specifica.

Nota tecnica: Se cambi l’ID del tuo header nel sito, ricordati di modificare questa riga nel codice: const HDR_SELECTOR = '#hdr'; (sostituisci #hdr con l’ID corretto del tuo header).

				
					
(function(){
  'use strict';

  // --- CONFIG ---
  // Se il tuo header ha un altro ID/class modifica qui:
  const HDR_SELECTOR = '#hdr';

  // Delay usato per garantire che Elementor abbia renderizzato i widget (ms)
  const ONLOAD_DELAY = 60;

  // --- UTILS ---
  function getHeaderHeight(){
    const hdr = document.querySelector(HDR_SELECTOR);
    return hdr ? Math.ceil(hdr.getBoundingClientRect().height) : 0;
  }

  function scrollToElement(el, smooth = true){
    if(!el) return;
    const hdrH = getHeaderHeight();
    const top = el.getBoundingClientRect().top + window.pageYOffset - hdrH;
    window.scrollTo({
      top: Math.max(0, Math.round(top)),
      behavior: smooth ? 'smooth' : 'auto'
    });
  }

  function isSamePageAnchor(href){
    // true se href è solo "#something" oppure "#"
    return href && href.startsWith('#') && (location.pathname === location.pathname);
  }

  // --- HANDLERS ---
  // Delegazione click su document per intercettare link anchor (anche aggiunti dinamicamente)
  document.addEventListener('click', function(e){
    const a = e.target.closest && e.target.closest('a[href]');
    if(!a) return;

    const href = a.getAttribute('href').trim();

    // Ignota: solo anchor semplici (es. "#section") sulla stessa pagina
    if(!href || !href.startsWith('#')) return;

    // Ignora link vuoti
    if(href === '#') return;

    const target = document.querySelector(href);
    if(!target) return; // niente da fare se target non esiste sulla pagina

    // Previeni comportamento default e scrolla con offset
    e.preventDefault();

    // Aggiorna l'URL senza ricaricare la pagina
    try { history.pushState(null, '', href); } catch (err) { location.hash = href; }

    scrollToElement(target, true);
  }, {passive: false});

  // Quando cambia l'hash direttamente (es. back/forward) -> scroll immediato (no smooth per compatibilità)
  window.addEventListener('hashchange', function(){
    const h = location.hash;
    if(!h) return;
    const target = document.querySelector(h);
    if(target) scrollToElement(target, false);
  });

  // All load: se c'è un hash iniziale scrollalo dopo un piccolo delay (per Elementor rendering)
  function initialHashScroll(){
    if(location.hash){
      const target = document.querySelector(location.hash);
      if(target){
        // primo tentativo senza smooth per evitare jump visibili, ma con delay per render
        setTimeout(function(){ scrollToElement(target, false); }, ONLOAD_DELAY);
      } else {
        // se non trovato subito, riproviamo una volta dopo un po' (utile con caricamenti dinamici)
        setTimeout(function(){
          const t = document.querySelector(location.hash);
          if(t) scrollToElement(t, false);
        }, 350);
      }
    }
  }

  // ricalcola se il header cambia dimensione: se l'header è dinamico potresti voler ri-applicare scroll
  // (qui teniamo una soluzione leggera: ri-scroll se la finestra viene ridimensionata e c'è hash)
  let resizeTimer = null;
  window.addEventListener('resize', function(){
    if(!location.hash) return;
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function(){
      const t = document.querySelector(location.hash);
      if(t) scrollToElement(t, false);
    }, 150);
  });

  // assicurati di eseguire su DOMContentLoaded e anche su window.load
  document.addEventListener('DOMContentLoaded', initialHashScroll);
  window.addEventListener('load', initialHashScroll);

  // Piccola compatibilità: alcuni widget Elementor possono essere renderizzati dopo il caricamento.
  // Questo tenta di eseguire ancora una volta qualche centinaio di ms dopo load.
  setTimeout(initialHashScroll, 500);

})();

				
			

Privacy Policy

Informativa sul trattamento dei dati personali ai sensi dell’Art. 13 del Regolamento (UE) 2016/679 (GDPR)

Data Ultimo Aggiornamento: 06/11/25


1. Identità e dati di contatto del Titolare del Trattamento

Titolare del trattamento dei dati personali è:

Angelo Marra
Indirizzo: Via Marcantonio Franceschini 10, 40128 Bologna (BO)
Partita IVA: IT04068171208
Codice Fiscale: MRRNGL80B13A509N
Email: angelo@marrisonlab.com
PEC: angelomarra80@pec.it


2. Dati trattati, Finalità e Base Giuridica

2.1. Dati Raccolti e Finalità (Modulo Contatti)

Dati Raccolti: Nome, Cognome, Indirizzo email, Messaggio e qualsiasi altro dato spontaneamente inserito dall’utente nel modulo.

Finalità: I Suoi Dati Personali sono trattati esclusivamente per rispondere alle Sue richieste di informazione, contatto, preventivo e/o per adempiere a misure precontrattuali adottate su Sua richiesta.

Base Giuridica: La base giuridica del trattamento è l’esecuzione di misure precontrattuali adottate su richiesta dello stesso (Art. 6.1, lett. b, GDPR).

2.2. Dati di Navigazione (Esplicativo)

I sistemi informatici acquisiscono dati (es. indirizzi IP) la cui trasmissione è implicita nell’uso dei protocolli di Internet. Tali dati sono utilizzati al solo fine di ricavare informazioni statistiche anonime e controllarne il corretto funzionamento. Si rimanda alla Cookie Policy per i dettagli sull’uso dei cookie.


3. Periodo di Conservazione dei Dati e Destinatari

Modalità del Trattamento: Il trattamento dei dati avviene mediante strumenti manuali, informatici e telematici.

Conservazione: I dati raccolti tramite il modulo di contatto sono conservati per il tempo strettamente necessario a evadere la Sua richiesta, salvo diversi obblighi di legge.

Destinatari: I Suoi dati non saranno diffusi. Potranno essere trattati da soggetti autorizzati (collaboratori) e da soggetti esterni (es. fornitori di servizi hosting) che agiscono come Responsabili del Trattamento, opportunamente nominati.


4. I Suoi Diritti (Art. 15-22 GDPR)

In qualità di Interessato, Lei ha il diritto di esercitare i seguenti diritti in qualsiasi momento:

  • Diritto di accesso (Art. 15)
  • Diritto di rettifica (Art. 16)
  • Diritto alla cancellazione (Diritto all’Oblio, Art. 17)
  • Diritto di limitazione di trattamento (Art. 18)
  • Diritto di opposizione al trattamento (Art. 21)
  • Diritto alla portabilità dei dati (Art. 20)

Per esercitare tali diritti, La preghiamo di contattare il Titolare all’indirizzo email angelo@marrisonlab.com o PEC angelomarra80@pec.it.

Inoltre, Lei ha il diritto di proporre reclamo all’Autorità di Controllo competente (Garante per la Protezione dei Dati Personali – www.garanteprivacy.it).