Manuel Oviedo 2 de diciembre de 2013 a las 08.22
   Imprimir artículo
elWebmaster.com

Usando botones con elemento “progress”, una opci贸n con estilo


html5logowideContinuando con la idea del elemento de progress introducido por HTML5 y presentado en un art铆culo previo. Ahora les mostraremos un enfoque distinto incluso a los implementados en en varios plugins, a continuaci贸n desarrollaremos medidores de progreso dentro de botones.

Estos botones ser谩n perfectos para mostrar el progreso al enviar formularios o cargar contenidos a trav茅s de AJAX. Asimismo, hay que usar los estilos CSS3 y transiciones para que sean f谩ciles de personalizar.

El c贸digo HTML

En la primera secci贸n de este tutorial escribiremos la estructura del HTML. Para hacerlo se usar谩 la forma est谩ndar de los documentos desarrollados en HTML5 los cuales incluyen dos recursos adicionales que ser谩n discutidos luego los cuales la hoja de estilo.css y el archivo Javascript script.js. Adicionalmente, se incluye la librer铆a de jQuery y la librer铆a de fuentes Raleway de Google.

index.html

  1. <!DOCTYPE html>
  2.  
  3. <html>
  4.  
  5.  <head>
  6.  
  7.  <meta charset="utf-8"/>
  8.  
  9.  <title>Tutorial: Medidor de progreso en botones</title>
  10.  
  11.  <link href="http://fonts.googleapis.com/css?family=Raleway:400,700
  12. " rel="stylesheet" />
  13.  
  14.  <!-- The Stylesheets -->
  15.  
  16.  <link href="assets/css/style.css" rel="stylesheet" />
  17.  
  18.  </head>
  19.  
  20.  <body>
  21.  
  22.  <h1>Boton Progreso</h1>
  23.  
  24.  <a id="submitButton" href="#" class="progress-button">Submit</a>
  25.  
  26.  <a id="actionButton" href="#" class="progress-button green" data-loading="Working.." data-
  27. finished="Finished!" data-type="background-bar">Accion!</a>
  28.  
  29.  <a id="generateButton" href="#" class="progress-button red" data-loading="Generating.." data-
  30. finished="Download" data-type="background-vertical">Generar</a>
  31.  
  32.  <h1>Control de Progreso</h1>
  33.  
  34.  <a id="controlButton" href="#" class="progress-button">Comenzar</a>
  35.  
  36.  <div class="control-area">
  37.  
  38.  <a class="command increment">Incrementar</a>
  39.  
  40.  <a class="command set-to-1">Comenzar en 1%</a>
  41.  
  42.  <a class="command set-to-50">Comenzar en 50%</a>
  43.  
  44.  <a class="command finish">Terminar</a>
  45.  
  46.  </div>
  47.  
  48.  <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  49.  
  50.  <script src="assets/js/script.js"></script>
  51.  
  52.  </body>
  53.  
  54. </html>

Como siempre, la estructura del HTML es la parte m谩s f谩cil de nuestro c贸digo, el bot贸n de progreso son definidos como enlaces regulares. Con el fin de ser reconocidos por el complemento y convertir los botones en barras de progresos, es necesario tener la clase .progress-button. Los botones pueden ser configurados con tres atributos de data-*, los cuales se presentan a continuaci贸n:

  • data-type especif铆ca que tipo de barra de progreso se mostrar谩. Por ahora s贸lo hay tres tipos: background-horizontal (por defecto), background-bar y background-vertical.
  • data-loading especifica el texto que ser谩 mostrado mientras la barra de progreso est谩 en animaci贸n. El valor por defecto es Loading.
  • data-finished setea el texto que el bot贸n de progreso mantendr谩 una vez terminada la ejecuci贸n y la animaci贸n. El valor por defecto es Done!

Si dejas de colocar algunos de los atributos, el valor ser谩 el por defecto.

El c贸digo jQuery

Una vez aqu铆 vamos a escribir c贸digo Javascript y jQuery para darle vida a los botones. El c贸digo es organizado como seis complementos de jQuery que son compartidos con el nombre de:
progressInitialize, progressStart, progressIncrement, progressTimed, progressSet and progressFinish. Se han colocado cierta cantidad de comentarios para que puedas seguir el proceso del c贸digo mejor.

assets/js/script.js

  1. $(document).ready(function(){
  2.  
  3.  // Convierte todos los enlaces con la clase del boton de progreso
  4.  
  5.  // a los botones actuales con el medidor de progreso.
  6.  
  7.  // Necesitas llamar esta funcion una vez la pagina haya cargado.
  8.  
  9.  // Si tu agregas botones luego, tu necesitaras llamar la funcion para ellos.
  10.  
  11.  $('.progress-button').progressInitialize();
  12.  
  13.  // Espera por los clicks en los primeros tres botones, y comienza la animacion del progreso.
  14.  
  15.  $('#submitButton').click(function(e){
  16.  
  17.  e.preventDefault();
  18.  
  19.  // Esta funcion mostrara un medidor de progreso por el tiempo acumulado.
  20.  
  21.  $(this).progressTimed(2);
  22.  
  23.  });
  24.  
  25.  $('#actionButton').click(function(e){
  26.  
  27.  e.preventDefault();
  28.  
  29.  $(this).progressTimed(2);
  30.  
  31.  });
  32.  
  33.  $('#generateButton').one('click', function(e){
  34.  
  35.  e.preventDefault();
  36.  
  37.  var button = $(this);
  38.  
  39.  button.progressTimed(3, function(){
  40.  
  41.  // En esta llamada, tu puedes configurar el atributo href del boton
  42.  
  43.  // colocando el URL del archivo generado. Para la demostracion, nosotros solamente
  44.  
  45.  // configuraremos un nuevo evento a los mensajes de alerta.
  46.  
  47.  button.click(function(){
  48.  
  49.  alert('Mostrando como funcionan las llamadas!');
  50.  
  51.  });
  52.  
  53.  });
  54.  
  55.  });
  56.  
  57.  // Manejo del progreso personalizada
  58.  
  59.  var controlButton = $('#controlButton');
  60.  
  61.  controlButton.click(function(e){
  62.  
  63.  e.preventDefault();
  64.  
  65.  // Tu puedes opcionalmente llamar la funcion progressStart.
  66.  
  67.  // Eso podria simular actividad cada dos segundos si
  68.  
  69.  // el medidor de progreso no ha sido incrementado.
  70.  
  71.  controlButton.progressStart();
  72.  
  73.  });
  74.  
  75.  $('.command.increment').click(function(){
  76.  
  77.  // Incrementa la barra de progreso en un 10%. Pasa un numero como
  78.  
  79.  // argumento para incrementar con una cantidad diferente.
  80.  
  81.  controlButton.progressIncrement();
  82.  
  83.  });
  84.  
  85.  $('.command.set-to-1').click(function(){
  86.  
  87.  // Coloca el porcentaje al medidor de progreso.
  88.  
  89.  controlButton.progressSet(1);
  90.  
  91.  });
  92.  
  93.  $('.command.set-to-50').click(function(){
  94.  
  95.  controlButton.progressSet(50);
  96.  
  97.  });
  98.  
  99.  $('.command.finish').click(function(){
  100.  
  101.  // Coloca 100% al medidor de progreso y muestra el texto listo.
  102.  
  103.  controlButton.progressFinish();
  104.  
  105.  });
  106.  
  107. });
  108.  
  109. // La funcionalidad del medidor de progreso esta disponible como una serie de complementos.
  110.  
  111. // Tu puedes colocar es codigo en un archivo separado si deseas mantener esto ordenado.
  112.  
  113. (function($){
  114.  
  115.  // Creamos una cantidad de complementos de jQuery que puedas usar
  116.  
  117.  // para inicializar y control el medidor de progreso.
  118.  
  119.  $.fn.progressInitialize = function(){
  120.  
  121.  // Esta funcion crea las etiquetas necesarias para el medidor de progreso
  122.  
  123.  // y establece unos listeners de eventos.
  124.  
  125.  // Cicla por todos los botones
  126.  
  127.  return this.each(function(){
  128.  
  129.  var button = $(this),
  130.  
  131.  progress = 0;
  132.  
  133.  // Extrae los atributos en las opciones de los objetos
  134.  
  135.  // Si faltan, recibir谩n valores por defecto.
  136.  
  137.  var options = $.extend({
  138.  
  139.  type:'background-horizontal',
  140.  
  141.  loading: 'Loading..',
  142.  
  143.  finished: 'Done!'
  144.  
  145.  }, button.data());
  146.  
  147.  // Agrega los datos de los atributos si ellos faltan del elemento.
  148.  
  149.  // Ellos son usados por nuestro codigo CSS para mostrar los mensajes
  150.  
  151.  button.attr({'data-loading': options.loading, 'data-finished': options.finished});
  152.  
  153.  // Agrega las etiquetas necesarias para la barra de progreso a el boton
  154.  
  155.  var bar = $('<span class="tz-bar ' + options.type + '">').appendTo(button);
  156.  
  157.  // El evento de progreso indica al bot贸n que actualice la barra de progreso
  158.  
  159.  button.on('progress', function(e, val, absolute, finish){
  160.  
  161.  if(!button.hasClass('in-progress')){
  162.  
  163.  // Este es el primer evento de progreso para el boton.
  164.  
  165.  // Vuelve a iniciar el progreso y remueve algunas clases que puedan haber quedado
  166.  
  167.  bar.show();
  168.  
  169.  progress = 0;
  170.  
  171.  button.removeClass('finished').addClass('in-progress')
  172.  
  173.  }
  174.  
  175.  // val, absolute and finish are event data passed by the progressIncrement
  176.  
  177.  // and progressSet methods that you can see near the end of this file.
  178.  
  179.  if(absolute){
  180.  
  181.  progress = val;
  182.  
  183.  }
  184.  
  185.  else{
  186.  
  187. []
  188.  progress += val;
  189.  
  190.  }
  191.  
  192.  if(progress >= 100){
  193.  
  194.  progress = 100;
  195.  
  196.  }
  197.  
  198.  if(finish){
  199.  
  200.  button.removeClass('in-progress').addClass('finished');
  201.  
  202.  bar.delay(500).fadeOut(function(){
  203.  
  204.  // Dispara el evento de culminacion del progreso
  205.  
  206.  button.trigger('progress-finish');
  207.  
  208.  setProgress(0);
  209.  
  210.  });
  211.  
  212.  }
  213.  
  214.  setProgress(progress);
  215.  
  216.  });
  217.  
  218.  function setProgress(percentage){
  219.  
  220.  bar.filter('.background-horizontal,.background-bar').width(percentage+'%');
  221.  
  222.  bar.filter('.background-vertical').height(percentage+'%');
  223.  
  224.  }
  225.  
  226.  });
  227.  
  228.  };
  229.  
  230.  // progressStart simula la actividad en el medidor de progreso. Lo llama primero, si el progreso tomara
  231.  
  232. un
  233.  
  234.  // largo tiempo en culminar.
  235.  
  236.  $.fn.progressStart = function(){
  237.  
  238.  var button = this.first(),
  239.  
  240.  last_progress = new Date().getTime();
  241.  
  242.  if(button.hasClass('in-progress')){
  243.  
  244.  // No se comienza por una segunda vez!
  245.  
  246.  return this;
  247.  
  248.  }
  249.  
  250.  button.on('progress', function(){
  251.  
  252.  last_progress = new Date().getTime();
  253.  
  254.  });
  255.  
  256.  // Cada medio segundo chequea si el progreso se ha incrementado en los dos 煤ltimos segundos
  257.  
  258.  var interval = window.setInterval(function(){
  259.  
  260.  if( new Date().getTime() > 2000+last_progress){
  261.  
  262.  // Cuando no haya habido actividad por dos segundos, entonces incremento la barra de
  263.  
  264. progreso par // a mostrar que algo esta pasando
  265.  
  266.  button.progressIncrement(5);
  267.  
  268.  }
  269.  
  270.  }, 500);
  271.  
  272.  button.on('progress-finish',function(){
  273.  
  274.  window.clearInterval(interval);
  275.  
  276.  });
  277.  
  278.  return button.progressIncrement(10);
  279.  
  280.  };
  281.  
  282.  $.fn.progressFinish = function(){
  283.  
  284.  return this.first().progressSet(100);
  285.  
  286.  };
  287.  
  288.  $.fn.progressIncrement = function(val){
  289.  
  290.  val = val || 10;
  291.  
  292.  var button = this.first();
  293.  
  294.  button.trigger('progress',[val])
  295.  
  296.  return this;
  297.  
  298.  };
  299.  
  300.  $.fn.progressSet = function(val){
  301.  
  302.  val = val || 10;
  303.  
  304.  var finish = false;
  305.  
  306.  if(val >= 100){
  307.  
  308.  finish = true;
  309.  
  310.  }
  311.  
  312.  return this.first().trigger('progress',[val, true, finish]);
  313.  
  314.  };
  315.  
  316.  // Esta funcion crea un medidor de progreso que culminar en una cantidad de tiempo especifico.
  317.  
  318.  $.fn.progressTimed = function(seconds, cb){
  319.  
  320.  var button = this.first(),
  321.  
  322.  bar = button.find('.tz-bar');
  323.  
  324.  if(button.is('.in-progress')){
  325.  
  326.  return this;
  327.  
  328.  }
  329.  
  330.  // Establece una declaraci贸n de transici贸n para la duraci贸n de la medida.
  331.  
  332.  // CSS realizara el trabajo de animar la barra de progreso por nostros.
  333.  
  334.  bar.css('transition', seconds+'s linear');
  335.  
  336.  button.progressSet(99);
  337.  
  338.  window.setTimeout(function(){
  339.  
  340.  bar.css('transition','');
  341.  
  342.  button.progressFinish();
  343.  
  344.  if($.isFunction(cb)){
  345.  
  346.  cb();
  347.  
  348.  }
  349.  
  350.  }, seconds*1000);
  351.  
  352.  };
  353.  
  354. })(jQuery);

Algo importante es que nosotros estamos configurando dos clases especiales en los botones, una es .in-progress la cual se usa mientras el medidor del progreso est谩 movi茅ndose, y .finished que se maneja cuando est谩 listo. Estos dos son usados para actualizar el texto de los botones como podr谩s ver en la siguiente secci贸n.

El c贸digo CSS

Antes se mencion贸 que se configuraron dos clases de CSS en los botones .in-progress y .finished. Ahora la pregunta es 驴C贸mo las clases cambian el texto del bot贸n? Simple, usamos un truco de CSS en el cual se implementa el operador attr de CSS3, el cual cuando se combina con content, puede setear el elemento de texto :before o :after al elemento del atributo usado. Eso se aclarar谩 mejor una vez lo veas por ti mismo:

css/styles.css

  1. .progress-button{
  2.  
  3.  display: inline-block;
  4.  
  5.  font-size:24px;
  6.  
  7.  color:#fff !important;
  8.  
  9.  text-decoration: none !important;
  10.  
  11.  padding:14px 60px;
  12.  
  13.  line-height:1;
  14.  
  15.  overflow: hidden;
  16.  
  17.  position:relative;
  18.  
  19.  box-shadow:0 1px 1px #ccc;
  20.  
  21.  border-radius:2px;
  22.  
  23.  background-color: #51b7e6;
  24.  
  25.  background-image:-webkit-linear-gradient(top, #51b7e6, #4dafdd);
  26.  
  27.  background-image:-moz-linear-gradient(top, #51b7e6, #4dafdd);
  28.  
  29.  background-image:linear-gradient(top, #51b7e6, #4dafdd);
  30.  
  31. }
  32.  
  33. /* Esconde el texto original del boton. Entonces el texto de carga o culminacion se mostrara en el elemento :after anterior. */
  34.  
  35. .progress-button.in-progress,
  36.  
  37. .progress-button.finished{
  38.  
  39.  color:transparent !important;
  40.  
  41. }
  42.  
  43. .progress-button.in-progress:after,
  44.  
  45. .progress-button.finished:after{
  46.  
  47.  position: absolute;
  48.  
  49.  z-index: 2;
  50.  
  51.  width: 100%;
  52.  
  53.  height: 100%;
  54.  
  55.  text-align: center;
  56.  
  57.  top: 0;
  58.  
  59.  padding-top: inherit;
  60.  
  61.  color: #fff !important;
  62.  
  63.  left: 0;
  64.  
  65. }
  66.  
  67. /* Si la clase .in-progress es configurada en el boton, muestra el contenido
  68.  
  69.  del atributo de carga de data del boton */
  70.  
  71. .progress-button.in-progress:after{
  72.  
  73.  content:attr(data-loading);
  74.  
  75. }
  76.  
  77. /* Lo mismo para la clase .finished */
  78.  
  79. .progress-button.finished:after{
  80.  
  81.  content:attr(data-finished);
  82.  
  83. }
  84.  
  85. /* La barra de color que crece dependiendo del progreso */
  86.  
  87. .progress-button .tz-bar{
  88.  
  89.  background-color:#e667c0;
  90.  
  91.  height:3px;
  92.  
  93.  bottom:0;
  94.  
  95.  left:0;
  96.  
  97.  width:0;
  98.  
  99.  position:absolute;
  100.  
  101.  z-index:1;
  102.  
  103.  border-radius:0 0 2px 2px;
  104.  
  105.  -webkit-transition: width 0.5s, height 0.5s;
  106.  
  107.  -moz-transition: width 0.5s, height 0.5s;
  108.  
  109.  transition: width 0.5s, height 0.5s;
  110.  
  111. }
  112.  
  113. /* La barra puede ser horizontal o vertical */
  114.  
  115. .progress-button .tz-bar.background-horizontal{
  116.  
  117.  height:100%;
  118.  
  119.  border-radius:2px;
  120.  
  121. }
  122.  
  123. .progress-button .tz-bar.background-vertical{
  124.  
  125.  height:0;
  126.  
  127.  top:0;
  128.  
  129.  width:100%;
  130.  
  131.  border-radius:2px;
  132.  
  133. }

El resto del c贸digo lo que hace es darle el estilo a los botones y la animaci贸n del medidor en los botones. En styles.css tambi茅n se incluyeron dos temas de colores adicionales a los que est谩n y alguna que otra regla.

Terminamos. El c贸digo utilizado puede ser f谩cilmente customizable. Simplemente abre el styles.css en tu editor favorito y cambias los colores, la letra o los otros estilos para que cuadren con tu p谩gina Web. Cambia el texto editando el HTML y los datos de los atributos.

Fuente original del art铆culo: Sofien Benrhouma Blog
Traducci贸n realizada por
elWebmaster.com


Enviar a Del.icio.us Enviar a Meneame Enviar a Digg Enviar a Fresqui Enviar a Enchilame

Comentarios (1)

  1. Martin dice:

    Excelente art铆culo!

Deja tu opinión

© 2007 - 2008 elWebmaster.com | Powered by Wordpress | Diseño CSS y XHTML válido. | Algunos íconos basados en FamFamFam Mini
Acceder