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