Las barras de progreso se han vuelto muy populares últimamente, y hay un montón de plugins que pueden ayudarte a agregar alguna a tu sitio web. Pero, ¿cómo hacer uno tú mismo? Cómo barras de progreso ya hay muchas implementadas, nosotros vamos a intentar hacer algo diferente incluyendo ese progreso dentro de unos botones. Serán perfectos para la visualización de progreso mientras la carga de un formulario o cargar contenido a través de AJAX. También utilizarán estilos CSS3 y transiciones para que sean fáciles de personalizar.
El HTML
En la primera sección del tutorial, vamos a escribir el código HTML. Se presenta en forma de un documento estándar HTML5 que incluye dos recursos adicionales que discutiremos más adelante - la styles.css hoja de estilo y los script.js JavaScript archivo. Además, he incluido la biblioteca jQuery, y el tipo de letra Raleway de fuentes web de Google.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Tutorial: Buttons with built-in progress meters</title>
<link href="http://fonts.googleapis.com/css?family=Raleway:400,700" rel="stylesheet" />
<!—La hoja de estilos -->
<link href="assets/css/style.css" rel="stylesheet" />
</head>
<body>
<h1>Botones de Progreso</h1>
<a id="submitButton" href="#" class="progress-button">Submit</a>
<a id="actionButton" href="#" class="progress-button green" data-loading="Working.." data-finished="Finished!" data-type="background-bar">Action!</a>
<a id="generateButton" href="#" class="progress-button red" data-loading="Generating.." data-finished="Download" data-type="background-vertical">Generate</a>
<h1>Control del Progreso</h1>
<a id="controlButton" href="#" class="progress-button">Start</a>
<div class="control-area">
<a class="command increment">Increment</a>
<a class="command set-to-1">Set to 1%</a>
<a class="command set-to-50">Set to 50%</a>
<a class="command finish">Finish</a>
</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
Los botones de progreso se definen como un simple hipervínculo con la etiqueta <a> a la que le añadiremos la clase progress-button para que sea reconocido por el plugin y convertido en botones con las barras de progreso incluidas. Los botones también se pueden configurar mediante el establecimiento de tres atributos del tipo data-* :
- data-type especifica qué tipo de barras de progreso se mostrará. Actualmente se admiten tres tipos: background-horizontal (por defecto), background-bar y background-vertical..
- data-loading especifica el texto que se muestra mientras la barra de progreso está en movimiento. El valor predeterminado es Loading ..
- data-finished es el texto que se mostrará en el botón cuando finalice el progreso. El valor por defecto es Done!
Si se omite un atributo, se utilizará el valor predeterminado.
El Código jQuery
En esta parte del tutorial, vamos a escribir el código JavaScript y jQuery para hacer que los botones funcionen. Este código está organizado en 6 plugins jQuery que comparten un nombre común
- progressInitialize
, progressStart
, progressIncrement
, progressTimed
, progressSet
y progressFinish
. Vamos a ver el código:
assets/js/script.js
$(document).ready(function(){
// Convertir todos los vínculos con la clase de progress-button a
// botones reales con medidores de progreso.
// Es necesario llamar a esta función una vez que se carga la página.
// Si agrega botones más tarde, tendrá que llamar a la función sólo para ellos.
$(".progress-button").progressInitialize();
// Al hacer click en los tres primeros botones iniciamos la animación
$("#submitButton").click(function(e){
e.preventDefault();
// Especificamos el tiempo para la barra de progreso
$(this).progressTimed(2);
});
$("#actionButton").click(function(e){
e.preventDefault();
$(this).progressTimed(2);
});
$("#generateButton").one("click", function(e){
e.preventDefault();
// recogemos la llamada
var button = $(this);
button.progressTimed(3, function(){
// En esta llamada, se puede establecer el atributo href del botón
// a la dirección URL del archivo generado. Para la demostración, sólo
// mostramos un mensaje a través de un alert
button.click(function(){
alert("Showing how a callback works!");
});
});
});
// Manejo de progreso personalizado
var controlButton = $("#controlButton");
controlButton.click(function(e){
e.preventDefault();
// Opcionalmente Usted puede llamar a la función progressStart.
// Se simulará la actividad cada 2 segundos si el
// indicador de progreso no se ha incrementado
controlButton.progressStart();
});
$(".command.increment").click(function(){
// Incrementar la barra de progreso con un 10%. Podemos pasar un número
// diferente como argumento para incrementar esa cantidad.
controlButton.progressIncrement();
});
$(".command.set-to-1").click(function(){
// Establecer el indicador de progreso con el porcentaje especificado
controlButton.progressSet(1);
});
$(".command.set-to-50").click(function(){
controlButton.progressSet(50);
});
$(".command.finish").click(function(){
// Establecer el contador de avance al 100% y mostrar el texto Done!.
controlButton.progressFinish();
});
});
// La funcionalidad del contador de avance se encuentra disponible como una serie de plugins.
// Usted puede poner este código en un archivo separado si desea mantener las cosas ordenadas.
(function($){
// Creación de un número de plugins jQuery que puede utilizar para
// inicializar y controlar los indicadores de progreso.
$.fn.progressInitialize = function(){
// Esta función inicializa el progreso y establece el detector de eventos
return this.each(function(){
var button = $(this),
progress = 0;
// Establecemos los atributos por defecto de los botones
var options = $.extend({
type:"background-horizontal",
loading: "Loading..",
finished: "Done!"
}, button.data());
// Añadimos los atributos de los elementos para que nuestro CSS los use para mostrar los mensajes
button.attr({"data-loading": options.loading, "data-finished": options.finished});
// Añádimos el progreso a la barra del botón
var bar = $("<span class="tz-bar " + options.type + "">").appendTo(button);
// El evento progress llama a la actualización de la barra de progreso
button.on("progress", function(e, val, absolute, finish){
if(!button.hasClass("in-progress")){
// Una vez ha terminado el progreso debemos reinicializar
// el progreso y eliminar algunas clases que puedan haber quedado
bar.show();
progress = 0;
button.removeClass("finished").addClass("in-progress")
}
if(absolute){
progress = val;
}
else{
progress += val;
}
if(progress >= 100){
progress = 100;
}
if(finish){
button.removeClass("in-progress").addClass("finished");
bar.delay(500).fadeOut(function(){
// Desencadena el evento progress-finish personalizado
button.trigger("progress-finish");
setProgress(0);
});
}
setProgress(progress);
});
function setProgress(percentage){
bar.filter(".background-horizontal,.background-bar").width(percentage+"%");
bar.filter(".background-vertical").height(percentage+"%");
}
});
};
// ProgressStart simula la actividad en el indicador de progreso. Llámalo primero,
// si el progreso tarda mucho en finalizar.
$.fn.progressStart = function(){
var button = this.first(),
last_progress = new Date().getTime();
if(button.hasClass("in-progress")){
//! No arranque por segunda vez
return this;
}
button.on("progress", function(){
last_progress = new Date().getTime();
});
// Cada medio segundo chequeo si el progreso
// se ha incrementado en los dos últimos segundos
var interval = window.setInterval(function(){
if( new Date().getTime() > 2000+last_progress){
// No ha habido ninguna actividad durante dos segundos. Incrementamos la barra de progreso
// un poco para mostrar que algo está pasando
button.progressIncrement(5);
}
}, 500);
button.on("progress-finish",function(){
window.clearInterval(interval);
});
return button.progressIncrement(10);
};
$.fn.progressFinish = function(){
return this.first().progressSet(100);
};
$.fn.progressIncrement = function(val){
val = val || 10;
var button = this.first();
button.trigger("progress",[val])
return this;
};
$.fn.progressSet = function(val){
val = val || 10;
var finish = false;
if(val >= 100){
finish = true;
}
return this.first().trigger("progress",[val, true, finish]);
};
// Esta función crea una barra de progreso que
// termina en un período de tiempo especificado.
$.fn.progressTimed = function(seconds, cb){
var button = this.first(),
bar = button.find(".tz-bar");
if(button.is(".in-progress")){
return this;
}
// Establecemos la transición para la duración del progreso.
// CSS hará el trabajo de animación de la barra de progreso
bar.css("transition", seconds+"s linear");
button.progressSet(99);
window.setTimeout(function(){
bar.css("transition","");
button.progressFinish();
if($.isFunction(cb)){
cb();
}
}, seconds*1000);
};
})(jQuery);
progressInitialize
establece un detector de eventos para el evento de progreso personalizado que las otras funciones llaman cada vez que tiene que ser actualizado. Gracias al evento personalizado, que puede tener funciones totalmente independientes como progressStart
, que gestiona su propio temporizador y el estado - progresInitialize
no necesita conocer progressStart
.
La otra cosa importante es que estamos creando dos clases especiales en los botones – .in-progress , mientras que el indicador de progreso se está moviendo, y .finished cuando esté listo. Se utilizan para actualizar el texto de los botones como se verá en la siguiente sección.
El CSS
Como ya he dicho, establecemos dos clases CSS en los botones– .in-progress y .finished. . Pero, ¿cómo añado una de estas clases para cambiar el texto del botón? Simple - estamos usando un truco CSS que implica el operador de CSS3 attr
que al combinarse con content
, puede fijar el texto de una etiqueta :before or :after ala del atributo del elemento. Será fácil de interpretar una vez veas el código:
assets/css/styles.css
.progress-button{
display: inline-block;
font-size:24px;
color:#fff !important;
text-decoration: none !important;
padding:14px 60px;
line-height:1;
overflow: hidden;
position:relative;
box-shadow:0 1px 1px #ccc;
border-radius:2px;
background-color: #51b7e6;
background-image:-webkit-linear-gradient(top, #51b7e6, #4dafdd);
background-image:-moz-linear-gradient(top, #51b7e6, #4dafdd);
background-image:linear-gradient(top, #51b7e6, #4dafdd);
}
/* Ocultamos los texto originales del botón. Una vez cargado se muestran en el evento :after */
.progress-button.in-progress,
.progress-button.finished{
color:transparent !important;
}
.progress-button.in-progress:after,
.progress-button.finished:after{
position: absolute;
z-index: 2;
width: 100%;
height: 100%;
text-align: center;
top: 0;
padding-top: inherit;
color: #fff !important;
left: 0;
}
/* Mientras está la clase .in-progress se muestra el contenido del atributo contents */
.progress-button.in-progress:after{
content:attr(data-loading);
}
/* La misma clase que .finished */
.progress-button.finished:after{
content:attr(data-finished);
}
/* La barra de color crece en función del progreso */
.progress-button .tz-bar{
background-color:#e667c0;
height:3px;
bottom:0;
left:0;
width:0;
position:absolute;
z-index:1;
border-radius:0 0 2px 2px;
-webkit-transition: width 0.5s, height 0.5s;
-moz-transition: width 0.5s, height 0.5s;
transition: width 0.5s, height 0.5s;
}
/* La barra de progreso puede ser horizontal o vertical */
.progress-button .tz-bar.background-horizontal{
height:100%;
border-radius:2px;
}
.progress-button .tz-bar.background-vertical{
height:0;
top:0;
width:100%;
border-radius:2px;
}
|
|
|
|
Hemos terminado!
El código está listo para las personalizaciones. Simplemente edita styles.css y cambiar los colores, fuentes o estilos para que coincidan con sus colores web. Cambia el texto al editar el HTML y los atributos de datos. O incluso se puede mejorar el código con alguna nueva característica. En este caso puedes compartirlo a través de los comentarios de este post.