Sweet Pages:una solución de paginación jQuery

Paginar el contenido es una opción estándar cuando se trata de grandes cantidades de datos. La implementación generalmente implica pasar el número de página al back-end, donde los datos apropiados se obtienen de la base de datos y se devuelven de alguna forma. Un proceso engorroso, pero es un mal necesario. ¿O lo es?

Cuando se trata de pequeños conjuntos de datos, ¿no sería mejor tener el contenido fácilmente disponible, pero todavía perfectamente organizado y de fácil acceso?

Hoy estamos creando un complemento de jQuery que le permitirá convertir una lista desordenada regular de elementos en un conjunto amigable con SEO de páginas fácilmente navegables. Se puede usar para hilos de comentarios, presentaciones de diapositivas o cualquier tipo de contenido estructurado.

La idea

Cuando se llama, el complemento jQuery divide los elementos LI contenidos en la lista desordenada en un número configurable de grupos. Estos grupos (o páginas) flotan a la izquierda y se ocultan de la vista, ya que desbordan la UL a la que se asigna overflow:hidden . Se generan una serie de enlaces de control, que deslizan la página apropiada de LIs a la vista.

También puede echar un vistazo a la siguiente ilustración.

Paso 1 - XHTML

El primer paso del tutorial es configurar el marcado XHTML. El complemento solo necesita una lista desordenada, UL, con algunos elementos li dentro. Aquí está el código de demo.html, que puede encontrar en el archivo de descarga:

demostración.html

<div id="main">
    <ul id="holder">
        <li>Lorem ipsum dolor sit amet...</li>
        <li>Lorem ipsum dolor sit amet...</li>
        <li>Lorem ipsum dolor sit amet...</li>
        <li>Lorem ipsum dolor sit amet...</li>
    </ul>
</div>

El div principal actúa como un contenedor para la UL paginada y tiene un bonito fondo gris claro. La lista desordenada contiene los elementos de la lista (de ahí el id).

En la mayoría de las situaciones prácticas, el marcado anterior probablemente se generaría mediante un script de back-end, lo que lo liberaría de tener que hacerlo manualmente. Podría tener todo tipo de contenido dentro de esos LI, ya que jQuery calcula dinámicamente la altura y el tamaño (solo un recordatorio:si planea usar imágenes, especifique el ancho y la altura).

Paso 2:CSS

Después de crear el marcado XHTML, podemos pasar a diseñarlo. Es una buena idea diseñar sus páginas como si no hubiera navegación, ya que el complemento depende de JavaScript. Esto significa que es posible que algunos usuarios no puedan ver ni usar la paginación.

estilos.css - Parte 1

#main{
    /* The main container div */
    position:relative;
    margin:50px auto;
    width:410px;
    background:url('img/main_bg.jpg') repeat-x #aeadad;
    border:1px solid #CCCCCC;
    padding:70px 25px 60px;

    /* CSS3 rounded cornenrs */

    -moz-border-radius:12px;
    -webkit-border-radius:12px;
    border-radius:12px;
}

#holder{
    /* The unordered list that is to be split into pages */

    width:400px;
    overflow:hidden;
    position:relative;
    background:url('img/dark_bg.jpg') repeat #4e5355;
    padding-bottom:10px;

    /*  CSS3 inner shadow (the webkit one is commeted, because Google Chrome
        does not like rounded corners combined with inset shadows): */

    -moz-box-shadow:0 0 10px #222 inset;
    /*-webkit-box-shadow:0 0 10px #222 inset;*/
    box-shadow:0 0 10px #222 inset;
}

.swControls{
    position:absolute;
    margin-top:10px;
}

Primero diseñamos el div principal y la lista desordenada (a esta última se le asigna el id de titular ).

Observe cómo usamos la sombra de cuadro de CSS3 propiedad con el recuadro atributo, para imitar una sombra interior. Al igual que con la mayoría de las reglas de CSS3, todavía tenemos que proporcionar prefijos específicos del proveedor para los navegadores Mozilla (Firefox) y Webkit (Safri y Chrome).

Puede ver que la versión webkit de la propiedad está comentada. Esto se debe a que hay un error en la representación de las sombras de los cuadros en Chrome, cuando se combinan con la propiedad border-radius (las sombras se representan como si el div fuera cuadrado, ignorando las esquinas redondeadas y arruinando así el efecto).

estilos.css - Parte 2

a.swShowPage{

    /* The links that initiate the page slide */

    background-color:#444444;
    float:left;
    height:15px;
    margin:4px 3px;
    text-indent:-9999px;
    width:15px;
    /*border:1px solid #ccc;*/

    /* CSS3 rounded corners */

    -moz-border-radius:7px;
    -webkit-border-radius:7px;
    border-radius:7px;
}

a.swShowPage:hover,
a.swShowPage.active{
    background-color:#2993dd;

    /*  CSS3 inner shadow */

    -moz-box-shadow:0 0 7px #1e435d inset;
    /*-webkit-box-shadow:0 0 7px #1e435d inset;*/
    box-shadow:0 0 7px #1e435d inset;
}

#holder li{
    background-color:#F4F4F4;
    list-style:none outside none;
    margin:10px 10px 0;
    padding:20px;
    float:left;

    /* Regular CSS3 box shadows (not inset): */

    -moz-box-shadow:0 0 6px #111111;
    -webkit-box-shadow:0 0 6px #111111;
    box-shadow:0 0 6px #111111;
}

#holder,
#holder li{
    /* Applying rouded corners to both the holder and the holder lis */
    -moz-border-radius:8px;
    -webkit-border-radius:8px;
    border-radius:8px;
}

.clear{
    /* This class clears the floated elements */
    clear:both;
}

En la segunda parte del código, diseñamos los enlaces de control de página y los elementos li. Como puede ver en la línea 46, estamos aplicando esquinas redondeadas tanto a la lista desordenada como a los elementos li en una declaración, lo que nos evita duplicar el código.

Por último, está la clase clear, que se utiliza para borrar los flotantes de los elementos, también conocida como técnica clearfix.

Paso 3:jQuery

Pasando a la última parte del tutorial, debemos incluir la última versión de la biblioteca jQuery en la página. En cuanto al rendimiento, es mejor incluir todos los archivos JavaScript externos justo antes de la etiqueta del cuerpo de cierre, ya que los scripts bloquean la representación de la página.

script.js - Parte 1

(function($){

// Creating the sweetPages jQuery plugin:
$.fn.sweetPages = function(opts){

    // If no options were passed, create an empty opts object
    if(!opts) opts = {};

    var resultsPerPage = opts.perPage || 3;

    // The plugin works best for unordered lists,
    // although OLs would do just as well:
    var ul = this;
    var li = ul.find('li');

    li.each(function(){
        // Calculating the height of each li element,
        // and storing it with the data method:

        var el = $(this);
        el.data('height',el.outerHeight(true));
    });

    // Calculating the total number of pages:
    var pagesNumber = Math.ceil(li.length/resultsPerPage);

    // If the pages are less than two, do nothing:
    if(pagesNumber<2) return this;

    // Creating the controls div:
    var swControls = $('<div class="swControls">');

    for(var i=0;i<pagesNumber;i++)
    {
        // Slice a portion of the li elements, and wrap it in a swPage div:
        li.slice(i*resultsPerPage,(i+1)*resultsPerPage).wrapAll('<div class="swPage" />');

        // Adding a link to the swControls div:
        swControls.append('<a href="" class="swShowPage">'+(i+1)+'</a>');
    }

    ul.append(swControls);

Crear un complemento jQuery no es tan difícil como podría pensar. Solo necesitamos crear una nueva función como propiedad de jQuery.fn (o $.fn , como se indica aquí). El esto de la función apunta al objeto jQuery original al que se llamó.

A partir de ahí, comprobamos la existencia de opts objeto y establecer resultados por página respectivamente. Este es el número de elementos li que se agruparán como una página.

Después de esto, calculamos el número total de páginas con Math.ceil() función. Redondea el resultado al entero mayor más próximo, lo que da el número correcto de páginas.

Ahora que tenemos la cantidad de páginas obtenidas, podemos ingresar un bucle for en el que dividimos los elementos li en porciones y los envolvemos en una swPage div, formando una página. Tenga en cuenta que llamar a jQuery slice() El método en la línea 36 crea un nuevo conjunto de elementos y deja intacto el conjunto original (por lo tanto, en cada iteración del ciclo for comenzamos con el conjunto original de li elementos).

script.js - Parte 2

  var maxHeight = 0;
    var totalWidth = 0;

    var swPage = ul.find('.swPage');
    swPage.each(function(){

        // Looping through all the newly created pages:

        var elem = $(this);

        var tmpHeight = 0;
        elem.find('li').each(function(){tmpHeight+=$(this).data('height');});

        if(tmpHeight>maxHeight)
            maxHeight = tmpHeight;

        totalWidth+=elem.outerWidth();

        elem.css('float','left').width(ul.width());
    });

    swPage.wrapAll('<div class="swSlider" />');

    // Setting the height of the ul to the height of the tallest page:
    ul.height(maxHeight);

    var swSlider = ul.find('.swSlider');
    swSlider.append('<div class="clear" />').width(totalWidth);

    var hyperLinks = ul.find('a.swShowPage');

    hyperLinks.click(function(e){

        // If one of the control links is clicked, slide the swSlider div
        // (which contains all the pages) and mark it as active:

        $(this).addClass('active').siblings().removeClass('active');

        swSlider.stop().animate({'margin-left': -(parseInt($(this).text())-1)*ul.width()},'slow');
        e.preventDefault();
    });

    // Mark the first link as active the first time the code runs:
    hyperLinks.eq(0).addClass('active');

    // Center the control div:
    swControls.css({
        'left':'50%',
        'margin-left':-swControls.width()/2
    });

    return this;

}})(jQuery);

En la segunda parte del script, recorremos las páginas recién creadas, establecemos sus tamaños y las hacemos flotar hacia la izquierda. En el proceso también buscamos la página más alta y establecemos la altura de la ul en consecuencia.

También envolvemos las páginas dentro de un swSlider div, que es lo suficientemente ancho como para mostrarlos uno al lado del otro. Después de esto, escuchamos el evento de clic en los enlaces de control y deslizamos el swSlider div con el método animado. Esto crea el efecto de diapositiva que se observa en la demostración.

script.js - Parte 3

$(document).ready(function(){
    /* The following code is executed once the DOM is loaded */

    // Calling the jQuery plugin and splitting the
    // #holder UL into pages of 3 LIs each:

    $('#holder').sweetPages({perPage:3});

    // The default behaviour of the plugin is to insert the
    // page links in the ul, but we need them in the main container:

    var controls = $('.swControls').detach();
    controls.appendTo('#main');

});

En la última parte del código, solo llamamos al complemento y pasamos la configuración perPage. Observe también el uso del método de separación, introducido en jQuery 1.4. Elimina elementos del DOM, pero deja intactos todos los detectores de eventos. Nos permite mover los controles fuera de la UL en la que se insertaron originalmente, manteniendo la función de clic en su lugar.

¡Con esto, nuestra dulce solución de paginación con jQuery y CSS3 está completa!

Conclusión

Con este complemento, puede impulsar cualquier tipo de hilos de comentarios, presentaciones de diapositivas, páginas de productos u otros tipos de datos. La ventaja es que si JavaScript está deshabilitado, aún terminas con un código semántico y compatible con SEO. Sin embargo, si planea mostrar grandes cantidades de datos, es mejor implementar una solución de back-end, ya que con el complemento todo el contenido se transfiere al navegador del visitante.

¿Qué opinas? ¿Cómo usarías este código?