Cambio dell’url senza il reload della pagina

Vediamo insieme come utilizzare HTML5 History API per poter modificare l'url senza ricaricare l'intera pagina.
Cambio dell’url senza il reload della pagina

Specifiche sulla traduzione

Di seguito la traduzione dell’articolo “Change browser url without page reloading with ajax request using JavaScript, HTML5 history API, jQuery, PHP like Facebook, Github navigation menu” di Arundavid.

Il problema del refresh

Quando lavori con ajax il problema principale è non poter cambiare l’URL nella barra degli indirizzi dopo aver caricato il nuovo contenuto. Un altro problema è che al reload della pagina il contenuto che verrà caricato non sarà lo stesso che era presente nella pagina, prima del refresh. Il problema potrebbe essere risolto inserendo gli hash tag nella url, ma tutti noi sappiamo che questo tipo di navigazione non è molto SEO friendly.

Hai mai notato quando navighi su facebook o Github con un browser che supporta l’HTML5, e clicchi su un link, il contenuto è caricato nella pagina tramite ajax e contemporaneamento cambia anche la URL di riferimento, per rispettare il contenuto della pagina che stai guardando ma senza l’hashtag nella URL.

Questo tipo di soluzione fa uso dell’HTML5 History API per poter modificare l’url senza il reload di pagina.

Il codice necessario

Considera come esempio un menù di navigazione per switchare da una sezione ad un’altra ed un elemento “content” dedicato al caricheremo dei contenuti via ajax. Il codice HTML è il seguente:

<div id="menu">
  <a href="menu1.php" class="tab">menu1</a>
  <a href="menu2.php" class="tab">menu2</a>
  <a href="menu3.php" class="tab">menu3</a>
</div>

Come prima cosa, usando jQuery, dovremo bloccare l’azione di default dei tag “a” con il seguente codice:

$(function(){
  $("a[class='tab']").click(function(e){
    //codice per bloccare il comportamento di default
    return false;
  });
});

Per visualizzare il contenuto ajax e per modificare l’url specifico nella barra degli indirizzi senza ricaricare la pagina usa il seguente codice.

$(function(){
  $("a[class='tab']").click(function(e){
    //e.preventDefault();
    /*
    Se decommenti la linea precedente, i browser che non supportano HTML5 non cambieranno la url; se la lasci commentata, i browser che non supportano HTML5 ricaricheranno la pagina indicata nell'href.
    */

    //Recupero l'indirizzo specificato nell'href dell'elemento cliccato
    pageurl = $(this).attr('href');

    //Recupero il contenuto ajax da mostrare nel div con id content
    $.ajax({
      url:pageurl+'?get=ajax',
      success: function(data){
        $('#content').html(data);
      }
    });

    //cambio l'url con il link specificato nell'href
    if(pageurl!=window.location){
      window.history.pushState({path:pageurl},'',pageurl);
    }

    //Blocco il refreshing della pagina.
    return false;
  });
});

Con il precedente codice, il pulsante back non funzionerà, quindi dobbiamo riscriverlo per recuperare il contenuto ajax senza ricaricare. Per farlo aggiungi il seguente codice javascript.

/* Il codice sottostante è per sovrascrivere il pulsante back, per recuperare il contenuto ajax senza il ricaricamento di pagina */
$(window).bind('popstate', function() {
  $.ajax({
    url:location.pathname+'?get=ajax',
    success: function(data){
      $('#content').html(data);
    }
  });
});

Conclusioni

Per i browser che non supportano HTML5 History API, i link ricaricheranno la pagina, ma se supportato, ricaricheranno il contenuto senza il refresh della stessa. Per i più creativi questo può essere il modo per creare delle transazioni tra un cambio di pagina è l’altro. Ecco il link per guardare la demo e scaricare il codice.

  • Grazie per il post. Ora confidiamo nel fatto che lo spider Google sia così saggio da non impazzire 🙂 Anche se avendo l’url corretto nell’href dovremmo non aver problemi! ;

    • Stefano Vollono

      Si infatti, lo spero proprio! Comunque ne approfitto per linkarti questo sito https://medium.com/the-conversation-uk/a1c332a996e. Il pulsantino in basso a sinistra ti porta all’articolo successivo con una transizione davvero ben fatta. Questo tipo di tecnologia apre le porte ad effetti e transizioni di pagina, che se fatti bene, possono essere veramente interessanti!

  • Ciao, questo codice si può utilizzare per avere dei post o commenti in tempo reale stile facebook?

    • Stefano Vollono

      Ciao Simone, l’ho sempre visto applicato alla navigazione di un sito. Sinceramente non saprei risponderti al riguardo. mi spiace.

  • Pingback: Medium, un ritrovato di moderne tecnologie. | Laboratorio CSS()

  • Question time, come faccio a cambiare il title della pagina che ottengo dopo il click? 😀

    • Stefano Vollono

      Ciao Davide, in teoria la funzione pushState() accetta tre parametri di cui uno è “title”. Questo paramentro, che accetta come chiave una stringa, però viene ignorato mi pare da firefox, quindi se vuoi modificare il title della pagina, bisognerebbe memorizzarlo manualmente in una variabile e settarlo nella callback function popstate.

      Ho trovato anche questa demo interessante. Nell’esempio non viene usato Ajax ma cmq il meccanismo alla base immagino sia lo stesso.

      http://demos.mattwest.io/history-api/index.html

  • Marco Beni

    Bell’articolo! 🙂 Finalmente ho capito come funziona.
    Tuttavia come potrei recuperare solo il contenuto di un div invece che la pagina intera?

    • ciao Marco,
      puoi tranquillamente dire a php (o al linguaggio che usi) di fornirti solo la porzione di contenuto che ti serve quando chiami la pagina con il parametro “get=ajax”
      Spero di essere stato chiaro, rimango comunque a disposizione per ulteriori chiarimenti.

      • Marco Beni

        Ciao Manuel grazie per la risposta.
        Putroppo non sono troppo pratico di questa sintassi, non saprei dove e come inserire il codice php per la richiesta.
        Sarebbe bello avere un piccolo snippet di esempio se possibile!

        • Ciao Marco,
          puoi usare la seguente sintassi php per decidere cosa mostrare e cosa non:

          qui quello che vuoi restituire alla richiesta della pagina.

          qui quello che vuoi nascondere, oppure la pagina completa.

          (per questioni di sicurezza del codice ho messo uno spazio tra )

          la chiamata ajax la fa fai come segue: http://[…]/pagina.php?get=ajax
          spero di esser stato utile!

          • Marco

            Manuel ti ringrazio! molto chiaro!

  • Ciao a tutti, vi faccio una domanda.
    Con questo codice, cosa succede se ad esempio vado direttamente in una pagina del sito senza cliccare il link? Ovvero: cliccando il link viene richiamata la pagina e caricato il suo contenuto all’interno del div #content, presupponendo quindi che header e footer sono già stati caricati da qualche parte e io – mediante il link – carico solo il contenuto.
    Se invece sulla barra indirizzi scrivo direttamente l’indirizzo di una pagina… come viene aperta questa? Si carica solo il suo contenuto oppure anche header e footer? Non so se ho reso l’idea.
    Nel mio caso specifico utilizzo un framework MVC, e ho un controller che carica la struttura della pagina con il contenuto della home page. Se faccio una richiesta ajax del genere per caricare una pagina, funziona tutto se clicco sulla voce di menu, perchè questa richiama il controller che carica il contenuto della pagina richiesta e lo piazza in un div #content.
    Ma se digito direttamente l’indirizzo della pagina… come faccio a caricare anche tutta la struttura del sito e non solo il contenuto della pagina?
    Grazie.

  • cristian visano

    ciao raffaele,hai risolto il problema?

  • Javier

    Ciao Manuel, ma il link per scaricare l’esempio non è più disponibile?

Search
Tags
Seleziona rubrica
Seleziona rubrica
Codice Github