Introducción a la History API de HTML5

El historial siempre es interesante, ¿verdad? En versiones anteriores de HTML, tuvimos un control limitado sobre el historial del navegador. Podríamos ir hacia adelante y hacia atrás utilizando los métodos disponibles, y eso era todo.

Con la History API de HTML5, tenemos más control sobre el historial del navegador. Por ejemplo, tenemos métodos para añadir una entrada en el historial, o cambiar la URL en la barra de direcciones sin actualizar la página.

¿Por qué una API para el historial?

En este artículo, te voy a enseñar la importancia que puede tener una API para gestionar el historial tal y como lo hace la History API. Antes de que existiera dicha API, a menudo se utilizaban valores hash para cambiar el contenido de la página especialmente en aplicaciones de una sola página pesadas, debido a que cambiar la URL no era posible sin actualizar la página. Además, cuando se cambia el valor hash de una dirección URL, no se realiza ningún cambio en el historial del navegador.

Ahora, sin embargo, ambas cosas están disponibles con la History API de HTML5. Mediante esta API es posible el desarrollo de aplicaciones pesadas de una sola página sin tener que recurrir a los valores hash. También nos permite desarrollar aplicaciones aptas para el SEO. Además, esta técnica nos permite reducir el ancho de banda, pero ¿cómo?

En este artículo, vamos a desarrollar una aplicación de una sola página con esta API para demostrar exactamente eso.

Eso significa que vamos a cargar todos los recursos necesarios en la primera carga de la página. A partir de ahí en adelante, la aplicación descargará solamente los contenidos necesarios. En otras palabras, en lugar de cargar todos los recursos todo el tiempo, cargaremos solamente los recursos requeridos a partir de una segunda solicitud de contenido.

Ten en cuenta que necesitas desarrollar algo de código del lado del servidor para entregar los recursos parciales en lugar del contenido completo de la página.

Soporte para navegadores

En el momento de escribir este artículo, el soporte para navegadores de la History API de HTML5 es bastante bueno, podemos revisar su estado aquí. Este enlace te proporciona una visión general de los navegadores compatibles, pero siempre es una buena práctica detectar las compatibilidades de esta API antes de usarla utilizando código. Para determinar mediante programación si el navegador es compatible con la API, echa un vistazo a la siguiente línea de código:

return !!(window.history && history.pushState);

Si está utilizando Modernizr, entonces echale un vistazo a este otro código:

if (Modernizr.history) {
    // History API Supported 
}

Si su navegador no soporta la History API, puedes utilizar los polyfills history.js.

Manipulando el historial

HTML5 nos ofrece dos nuevos métodos:

- history.pushState ()
- history.replaceState ()

Estos métodos nos permiten añadir y actualizar respectivamente el estado del historial. Ambos funcionan de la misma manera y esperan el mismo número de parámetros. Además de estos métodos, tenemos el evento popstate. Más adelante, en este artículo, veremos cómo y cuándo utilizar este evento popstate.

Como hemos dicho antes, pushState y replaceState esperan el mismo número de parámetros que son:

- state que puede almacenar una cadena JSON y estará disponible para el evento popstate.
- title es un parámetro ignorado por la mayoría de los navegadores por ahora, así que mejor ponerlo como null.
- url puede representar cualquier URL. Se actualizará con la dirección del navegador, y no le importa si existe de verdad esa URL o no. Y lo más importante, no actualizará tu página web.

Las principales diferencias entre estos métodos son que pushState añade una nueva entrada en la pila del historial y replaceState reemplazará el valor actual del historial en lugar de añadir un registro nuevo. Si no te ha quedado del todo claro, a continuación, te lo voy a mostrar con un sencillo ejemplo.

Supongamos que tenemos dos manzanas, una en una canasta y otra en la mano. Mediante el método pushState tendremos una nueva manzana en la mano, y la que teníamos antes en la mano, la dejaríamos en la canasta. Mediante el método replaceState, nos cambiarían esa manzana que teníamos en la mano por otra distinta, siendo sustituida así la primera manzana.

Hasta ahora, hemos cubierto los métodos pushState y replaceState con el fin de controlar el historial del navegador, pero supongamos que tenemos una variedad de historial falso que hemos totalizado en el navegador. El usuario puede o no ser redirigido a dichas páginas. En tal caso, será un problema cuando el usuario navegue con los botones de atrás y adelante del propio navegador.

Popstate es un evento que se disparará cuando se navegue a través de la entrada del historial, ya sea utilizando los botones de hacia atrás o hacia adelante, o bien usando los métodos history.go o history.back.

Demo

HTML

<div class="container">
    <div class="row">
        <ul class="nav navbar-nav">
            <li><a href="home.html" class="historyAPI">Home</a></li>
            <li><a href="about.html" class="historyAPI">About</a></li>
            <li><a href="contact.html" class="historyAPI">Contact</a></li>
        </ul>
    </div>
    <div class="row">
        <div class="col-md-6">
            <div class="well">
                Click on Links above to see history API usage using <code>pushState</code> method.
            </div>
        </div>
        <div class="row">    
            <div class="jumbotron" id="contentHolder">
                <h1>Home!</h1>
                <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            </div>
        </div>
    </div>
</div>

Javascript

<script type="text/javascript">
    jQuery('document').ready(function(){
         
        jQuery('.historyAPI').on('click', function(e){
            e.preventDefault();
            var href = $(this).attr('href');
             
            // Getting Content
            getContent(href, true);
             
            jQuery('.historyAPI').removeClass('active');
            $(this).addClass('active');
        });
         
    });
     
    // Adding popstate event listener to handle browser back button  
    window.addEventListener("popstate", function(e) {
         
        // Get State value using e.state
        getContent(location.pathname, false);
    });
     
    function getContent(url, addEntry) {
        $.get(url)
        .done(function( data ) {
             
            // Updating Content on Page
            $('#contentHolder').html(data);
             
            if(addEntry == true) {
                // Add History Entry using pushState
                history.pushState(null, null, url);
            }
             
        });
    }
</script>

Fuente: Avinash Zala

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP