1. Code
  2. JavaScript

Crear una barra de progreso con Javascript

Scroll to top

Spanish (Español) translation by Luis Chiabrera (you can also view the original English article)

La barra de progreso es uno de los últimos componentes que se agregarán a la excelente biblioteca de widgets de interfaz de usuario y ayudantes de interacción creados sobre jQuery. Fue introducido en la última versión de la biblioteca, que al momento de escribir es 1.7.

La barra de progreso actualmente solo está determinada, lo que significa que cuando la actualizamos, tenemos que decirle explícitamente cuál es su valor, y debemos saber de antemano cuándo se completa el proceso que se utiliza para medir. Actualmente, este widget no es la mejor opción para un proceso que tomará un tiempo indeterminado en completarse. Es un widget muy simple con una pequeña API que expone un número limitado de propiedades y métodos, pero aún puede ser muy efectivo y es excelente para proporcionar comentarios visuales a los visitantes sobre el porcentaje de un proceso que queda antes de que se complete.

Comenzando

Necesitaremos una copia de la versión actual de jQuery UI, que se puede obtener del creador de descargas en https://jqueryui.com/download. Una vez que lo hayamos descargado, tendremos que descomprimirlo para que se conserve la estructura de directorios existente. Deberíamos crear un nuevo directorio en nuestra computadora llamado jQuery UI y luego dentro de este crear otra carpeta nueva llamada jqueryui1.7. El archivo debe descomprimirse en la carpeta jqueryui1.7.

El archivo contendrá todo lo que necesitamos para comenzar; versiones minimizadas y sin comprimir de todos los archivos de la biblioteca, algunos archivos de tema (el tema predeterminado es la suavidad correctamente nombrada) e incluso la última versión de la biblioteca jQuery subyacente.

La barra de progreso se basa en varios archivos para funcionar; Estos se enumeran a continuación en el orden en que deben agregarse a nuestra página:

  • ui.core.css
  • ui.theme.css
  • ui.progressbar.css
  • jquery[currentversion].js
  • ui.core.js
  • ui.progressbar.js

Los primeros tres archivos son parte del extenso marco CSS y se usan para dar a la barra de progreso su aspecto distintivo. No necesitamos seguir con este tema en una implementación del mundo real; Tenemos muchas opciones de personalización, incluida una gran cantidad de temas preconfigurados disponibles directamente desde Themeroller, un tema personalizado que podemos diseñar nosotros mismos usando Themeroller, o incluso un tema personalizado que creamos manualmente anulando las reglas definidas en las hojas de estilo predeterminadas. Sin embargo, no haremos ninguna de esas cosas en este tutorial, pero podemos hacer uso de algunas de las clases proporcionadas por el marco.

La Página Subyacente

Este widget necesita muy poco marcado subyacente; todo lo que necesitamos, además de los recursos de la biblioteca enumerados anteriormente, es un elemento contenedor simple. En tu editor de texto, crea el siguiente shell de página con los recursos necesarios y el elemento contenedor:

1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
<html>
3
  <head>
4
    <link rel="stylesheet" type="text/css" href="jqueryui1.7/development-bundle/themes/smoothness/ui.core.css">
5
    <link rel="stylesheet" type="text/css" href="jqueryui1.7/development-bundle/themes/smoothness/ui.theme.css">
6
    <link rel="stylesheet" type="text/css" href="jqueryui1.7/development-bundle/themes/smoothness/ui.progressbar.css">
7
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
8
    <title>jQuery UI Progress Bar</title>
9
  </head>
10
  <body>
11
    <div id="container"></div>
12
    <script type="text/javascript" src="jqueryui1.7/development-bundle/jquery-1.3.2.js"></script>
13
    <script type="text/javascript" src="jqueryui1.7/development-bundle/ui/ui.core.js"></script>
14
    <script type="text/javascript" src="jqueryui1.7/development-bundle/ui/ui.progressbar.js"></script>
15
    <script type="text/javascript">
16
	
17
    </script>
18
  </body>
19
</html>

Guarda esto como progressBar.html en el directorio raíz de la interfaz de usuario jQuery. Ponemos las hojas de estilo justo al comienzo del archivo y las secuencias de comandos justo al final; Esto se debe a razones de rendimiento, ya que las páginas cargan el contenido más rápido cuando no intentan cargar JavaScript al mismo tiempo. Esta es una práctica de rendimiento bien documentada que se cumple mejor. Hemos dejado una etiqueta de script vacía en la parte inferior de la página; agreguemos un código a continuación:

1
$(function() {
2
3
  //call progress bar constructor			
4
  $("#container").progressbar();
5
});

Para inicializar la barra de progreso predeterminada, todo lo que hacemos es llamar a su método constructor, barra de progreso, en el elemento contenedor en el que se va a representar el widget. Cuando ejecutas esta página en su navegador, deberías ver que la barra de progreso se ha creado y llena automáticamente el ancho de su contenedor, que en este caso es el cuerpo de la página:

Estableciendo el valor de la barra de progreso

El valor de la barra de progreso se establecerá en cero de forma predeterminada, por lo que aparece vacío en la captura de pantalla anterior. Para llenar la barra de progreso, necesitamos establecer la propiedad de valor; cambia la función constructora para que aparezca de la siguiente manera:

1
//call progress bar constructor
2
$("#container").progressbar({ value: 50 });

La propiedad de valor determina el porcentaje de la barra de progreso que se llena, lo que proporciona una excelente respuesta visual al visitante sobre la cantidad de tarea que queda por completar. La barra de progreso ahora debería estar medio llena, como en la siguiente captura de pantalla:

Obteniendo el valor de la barra de progreso

Obtener el valor actual del widget es tan fácil como establecerlo; Podemos usar uno de sus métodos para devolver la propiedad de valor actual. Después del constructor inicial, agrega el siguiente código: //set mouseover para la barra de progreso

1
$("#container").mouseover(function() {
2
				
3
  //display the current value
4
  $("<p>").attr("id", "percentage").text($("#container").progressbar("option", "value") + "% complete").appendTo("body");					
5
});
6
				
7
//set mouseout for progress bar
8
$("#container").mouseout(function() {
9
				  
10
  //hide value
11
  $("#percentage").remove();
12
});

Hemos agregado dos funciones anónimas simples que se activan en los eventos de mouseover y mouseout activados por la barra de progreso (ten en cuenta que estos son eventos DOM estándar, no eventos de barra de progreso personalizados). Todo lo que hacemos en la primera función es crear un nuevo párrafo con el valor actual de la barra de progreso como texto interno y agregarlo a la página.

El valor se recupera utilizando el método de opción. El argumento pasado al método es el nombre de la propiedad que nos gustaría recuperar. La segunda función simplemente elimina el mensaje nuevamente. El mensaje se muestra en la siguiente captura de pantalla:

Propiedades, eventos y métodos.

La propiedad u opción de valor es actualmente la única propiedad configurable de la barra de progreso; En este ejemplo, lo configuramos cuando el widget se inicializa pasándolo como propiedad de un objeto de configuración. Para establecer esta propiedad después de que el widget se haya inicializado, usaríamos el método de opción. Para usar este método en modo setter, necesitamos pasar un segundo parámetro que especifique el nuevo valor, como este:

1
progressbar("option", "value", 75)

Puede que te preguntes por qué dije "un segundo parámetro" cuando claramente hay tres argumentos en la línea de código anterior. Aunque estamos utilizando el método de opción, en realidad no lo estamos llamando directamente. En cambio, llamamos al método constructor nuevamente, pero le decimos que nos gustaría llamar al método de opción. El widget llamará al método internamente, pasando los dos parámetros ("valor" y 75) que pasamos al constructor después del nombre del método.

La barra de progreso expone un solo evento, el evento de cambio, que proporciona un mecanismo para que podamos conectarnos para que podamos responder a los cambios en su valor. Este es un evento personalizado para que podamos detectarlo y reaccionar ante él de dos maneras diferentes. Podemos definir una función anónima como el valor de la propiedad change en un objeto de configuración, como lo hicimos con la propiedad value, o podemos usar el método de enlace de jQuery para especificar la función anónima a ejecutar. Una sutil diferencia entre los dos es que el código especificado utilizando el método de enlace se ejecutará primero. La barra de progreso API expone cinco métodos, que se enumeran a continuación:

  • destruir
  • desactivar
  • activar
  • opción
  • valor

Todos estos métodos se usan exactamente de la misma manera que el método de opción que hemos visto; llamando al método constructor especificando el nombre del método y cualquier parámetro que nos gustaría pasar. La mayoría de estos deberían explicarse por sí mismos.

Usando la barra de progreso

Este ejemplo hasta ahora ha sido muy básico, para aquellos de ustedes que pueden no haber usado jQuery UI antes. Intensifiquemos un poco las cosas y creemos algo parecido al tipo de cosas que nos gustaría hacer en una implementación adecuada. Este ejemplo también será básico, pero debería dar una idea mucho mejor de cómo se puede hacer que el widget funcione para nosotros. Nuestra página final se verá así:

Comienza con la siguiente página subyacente en un nuevo archivo en tu editor de texto:

1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
<html>
3
  <head>
4
    <link rel="stylesheet" type="text/css" href="jqueryui1.7/development-bundle/themes/smoothness/ui.core.css">
5
    <link rel="stylesheet" type="text/css" href="jqueryui1.7/development-bundle/themes/smoothness/ui.theme.css">
6
    <link rel="stylesheet" type="text/css" href="jqueryui1.7/development-bundle/themes/smoothness/ui.progressbar.css">
7
    <link rel="stylesheet" type="text/css" href="regForm.css">
8
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
9
    <title>jQuery UI Progress Bar</title>
10
  </head>
11
  <body>
12
    <div class="form-container ui-helper-clearfix ui-corner-all">
13
      <h1>Registration Form</h1>
14
      <p>Progress:</p>
15
      <div id="progress"></div><label id="amount">0%</label>
16
        <form action="serverScript.php">
17
          <div id="panel1" class="form-panel">
18
            <h2>Personal Details</h2>
19
              <fieldset class="ui-corner-all">
20
	<label>Name:</label><input type="text">
21
	<label>D.O.B:</label><input type="text">
22
	<label>Choose password:</label><input type="password">
23
	<label>Confirm password:</label><input type="password">
24
              </fieldset>
25
            </div>
26
            <div id="panel2" class="form-panel ui-helper-hidden">
27
              <h2>Contact Details</h2>
28
              <fieldset class="ui-corner-all">
29
                <label>Email:</label><input type="text">
30
	<label>Telephone:</label><input type="text">
31
	<label>Address:</label><textarea rows="3" cols="25"></textarea>
32
              </fieldset>
33
            </div>
34
            <div id="thanks" class="form-panel ui-helper-hidden">
35
              <h2>Registration Complete</h2>
36
              <fieldset class="ui-corner-all">
37
  	<p>Thanks for registering!</p>
38
              </fieldset>
39
            </div>
40
            <button id="next">Next ></button><button id="back" disabled="disabled">< Back</button>
41
          </form>
42
        </div>
43
        <script type="text/javascript" src="jqueryui1.7/development-bundle/jquery-1.3.2.js"></script>
44
        <script type="text/javascript" src="jqueryui1.7/development-bundle/ui/ui.core.js"></script>
45
        <script type="text/javascript" src="jqueryui1.7/development-bundle/ui/ui.progressbar.js"></script>
46
        <script type="text/javascript">

Guarda esto como regForm.html en la carpeta jQuery UI. En la parte superior de la página, vinculamos al marco CSS; Esto es principalmente para agregar el estilo requerido para la barra de progreso, pero también podemos hacer uso de algunas de las clases que proporciona en nuestros propios elementos. También agregamos una hoja de estilo personalizada que crearemos pronto.

El cuerpo de la página contiene algunos elementos de diseño y algunos nodos de texto, pero los elementos principales son el contenedor de la barra de progreso y el formulario. El formulario se separa en varias secciones diferentes utilizando elementos div y de conjunto de campos. La razón de esto es para que podamos ocultar parte del formulario para que parezca que abarca varias páginas.

Agregamos un párrafo y una etiqueta al lado de la barra de progreso, los colocaremos para que aparezcan dentro de la barra de progreso. El párrafo contiene una cadena de texto simple. La etiqueta se usará para mostrar el valor de progreso actual.

El contenedor externo recibe varios nombres de clase; el primero es para que podamos aplicar un estilo personalizado al elemento, pero los segundos dos están destinados a diferentes características del marco CSS. La clase ui-helper-clearfix se usa para borrar automáticamente los elementos flotantes y es una excelente manera de reducir el desorden de elementos div adicionales e innecesarios.

La clase ui-corner-all se usa para dar esquinas redondeadas al elemento contenedor (así como a la barra de progreso que los tiene automáticamente, y a nuestros elementos de conjunto de campos) utilizando varias reglas de estilo patentadas. Estos solo son compatibles con los navegadores basados en gecko y webkit, pero en la naturaleza de la mejora progresiva, es perfectamente aceptable usarlos. La mejora progresiva dicta que podemos proporcionar un estilo mejorado en nuestras páginas web para navegadores que sean capaces de mostrarlo. Otros navegadores solo tendrán un contenedor de esquinas cuadradas.

Usamos otra clase del marco CSS dentro del formulario; varios paneles deben estar ocultos cuando se carga la página por primera vez, por lo tanto, podemos utilizar la clase ui-helper-hidden para asegurarnos de que estén configurados para mostrar: ninguno, cuando queremos mostrarlos, todo lo que tenemos que hacer es eliminar este nombre de clase.

En la parte inferior del cuerpo (por razones de rendimiento; ¡esto realmente funciona por cierto!) Enlazamos a los recursos JavaScript necesarios de la biblioteca. El último elemento del script está vacío y esperando el código que dará vida al formulario y a la barra de progreso. Agreguemos eso a continuación:

1
$(function() {
2
3
  //call progress bar constructor
4
  $("#progress").progressbar({ change: function() {
5
6
    //update amount label when value changes
7
    $("#amount").text($("#progress").progressbar("option", "value") + "%");
8
  } });
9
10
  //set click handler for next button
11
  $("#next").click(function(e) {
12
13
  //stop form submission
14
  e.preventDefault();
15
16
  //look at each panel
17
  $(".form-panel").each(function() {
18
19
    //if it's not the first panel enable the back button
20
    ($(this).attr("id") != "panel1") ? null : $("#back").attr("disabled", "");
21
22
	//if the panel is visible fade it out
23
	($(this).hasClass("ui-helper-hidden")) ? null : $(this).fadeOut("fast", function() {
24
25
	  //add hidden class and show the next panel
26
	  $(this).addClass("ui-helper-hidden").next().fadeIn("fast", function() {
27
28
	    //if it's the last panel disable the next button
29
    	    ($(this).attr("id") != "thanks") ? null : $("#next").attr("disabled", "disabled");
30
								
31
	    //remove hidden class from new panel
32
	    $(this).removeClass("ui-helper-hidden");
33
								
34
	    //update progress bar
35
	    $("#progress").progressbar("option", "value", $("#progress").progressbar("option", "value") + 50);
36
	  });
37
      });
38
    });
39
  });
40
41
});

Dentro del acceso directo document.ready tenemos la función de constructor para la barra de progreso; Pasamos al constructor un objeto de configuración literal que contiene una sola propiedad. Esta es la propiedad de cambio y nos permite proporcionar una función anónima para ejecutar cada vez que se detecta el evento de cambio personalizado. Podemos usar este evento para actualizar la etiqueta que vamos a colocar dentro de la barra de progreso.

Cada vez que se active el evento, tomaremos el valor actual de la barra de progreso utilizando el método de opción y estableceremos el valor como el texto de la etiqueta. El evento se activa después de que se produce el cambio, por lo que el valor que obtenemos siempre será el nuevo valor.

A continuación tenemos un controlador de clic para el botón siguiente>; Cuando se hace clic en este botón, la "página" actual del formulario cambiará, a través de una serie de animaciones, y el valor de la actualización de la barra de progreso. También necesitamos hacer algunas otras cosas. El comportamiento predeterminado de un botón dentro de un formulario es enviar el formulario, lo que no queremos hacer en esta etapa, por lo que lo primero que hace nuestro controlador de clics es evitar que el formulario se envíe utilizando la función de JavaScript preventDefault (). Esto se llama en el objeto de evento, que se pasa automáticamente a la función anónima.

Luego miramos a través de cada uno de los paneles separados en el formulario para determinar el panel actual; lo primero que hacemos es verificar que el panel actual no sea el primer panel y, si no lo es, habilitamos el botón de retroceso que está deshabilitado de manera predeterminada. Solo se mostrará un panel a la vez, por lo que encontramos el panel que no tiene la clase ui-helper-hidden y lo atenuamos. Especificamos una función de devolución de llamada anónima para ejecutar una vez que finaliza el desvanecimiento.

Dentro de esta segunda función, seleccionamos el siguiente elemento y lo mostramos; si el siguiente elemento es el panel final, que tiene una identificación de agradecimiento, deshabilitamos el botón siguiente>. Aunque no nos preocupamos por el envío real del formulario en este ejemplo, aquí es donde podríamos enviar los datos recopilados del formulario al servidor. Eliminamos la clase ui-helper-hidden ya que el panel ahora es visible.

Finalmente, utilizamos el método de opción una vez más, esta vez en modo setter, para establecer el nuevo valor de la barra de progreso. El nuevo valor que pasamos al método como segundo parámetro es simplemente el valor actual más 50, ya que solo hay 2 partes del formulario. Esta última parte activará la función que actualiza la etiqueta.

A continuación, debemos agregar un controlador de clics muy similar para el

1
//set click handler for back button
2
$("#back").click(function(e) {
3
				  
4
  //stop form submission
5
  e.preventDefault();
6
					
7
  //look at each panel
8
  $(".form-panel").each(function() {
9
					  					
10
    //if it's not the last panel enable the next button
11
    ($(this).attr("id") != "thanks") ? null : $("#next").attr("disabled", "");
12
					  
13
    //if the panel is visible fade it out
14
    ($(this).hasClass("ui-helper-hidden")) ? null : $(this).fadeOut("fast", function() {
15
						  
16
      //add hidden class and show the next panel
17
      $(this).addClass("ui-helper-hidden").prev().fadeIn("fast", function() {
18
							
19
        //if it's the first panel disable the back button
20
    	  ($(this).attr("id") != "panel1") ? null : $("#back").attr("disabled", "disabled");
21
										
22
	  //remove hidden class from new panel
23
	  $(this).removeClass("ui-helper-hidden");
24
								
25
	  //update progress bar
26
	  $("#progress").progressbar("option", "value", $("#progress").progressbar("option", "value") - 50);
27
      });
28
    });
29
  });
30
});

Este es ahora todo el código que necesitaremos, todo lo que tenemos que hacer ahora es agregar un poco de CSS básico para presentar el ejemplo; en un nuevo archivo en tu editor de texto agrega el siguiente código:

1
h1, h2 { font-family:Georgia; font-size:140%; margin-top:0; }
2
h2 { font-size:100%; margin:20px 0 10px; text-align:left; }
3
.form-container {
4
  width:400px; margin:0 auto; position:relative; font-family:Verdana;
5
  font-size:80%; padding:20px; background-color:#e0e3e2;
6
  border:3px solid #abadac;
7
}
8
.form-panel { width:400px; height:241px; }
9
.form-panel fieldset {
10
  width:397px; height:170px; margin:0 auto; padding:22px 0 0;
11
  border:1px solid #abadac; background-color:#ffffff;
12
}
13
.form-panel label {
14
  width:146px; display:block; float:left; text-align:right;
15
  padding-top:2px; margin-right:10px;
16
}
17
.form-panel input, .form-panel textarea {
18
  float:left; width:200px; margin-bottom:13px;
19
}
20
.form-container button { float:right; }
21
p {
22
  margin:0; font-size:75%; position:absolute; left:30px; top:60px;
23
  font-weight:bold;
24
}
25
#amount {
26
  position:absolute; right:30px; top:60px; font-size:80%;
27
  font-weight:bold;
28
}
29
#thanks { text-align:center; }
30
#thanks p {
31
  margin-top:48px; font-size:160%; position:relative; left:0; top:0;
32
}

Guarda esto como regForm.css en la misma carpeta que el archivo HTML. Ahora deberíamos tener una página de trabajo con una barra de progreso cableada. Cuando ejecutamos la página, deberíamos encontrar que podemos navegar a través de cada panel del formulario, y la barra de progreso se actualizará en consecuencia:

Resumen

En este artículo, analizamos la barra de progreso extremadamente útil, que podemos usar como una ayuda visual para decir a los visitantes cuánto tiempo más tardará un proceso específico en completarse porcentualmente. Proporciona una presentación atractiva y útil de la información, de manera que nuestros visitantes puedan entenderla fácilmente.

Analizamos la propiedad y el evento expuestos por su API y analizamos uno de los métodos a los que podemos llamar para que la barra de progreso haga algo. El ejemplo con el que terminamos debería funcionar perfectamente en todos los navegadores principales, aunque se ve un poco desordenado en el buen IE antiguo (lo cual sería muy fácil de solucionar si estuviéramos dispuestos a hacerlo).

  • Suscríbete a la Fuente RSS de NETTUTS para obtener más artículos y artículos de desarrollo web diarios.