progreso ejemplos bootstrap barra bar javascript jquery css progress

ejemplos - progress bar javascript



Actualizar barra de progreso en cada bucle (10)

¿Qué quieres hacer? ¿Por qué lo necesitas? Solo debes usar una barra de progreso cuando tengas que esperar a que algo termine. Pero no sabemos lo que haces en tu página.

  1. Si desea visualizar el progreso de una carga ajax:

    $.ajax({ ... xhr: function() { var xhr = $.ajaxSettings.xhr(); $(xhr.upload).bind("progress", function(event) { var e = event.originalEvent; var percent = 0; if (e.lengthComputable) percent = Math.ceil(e.loaded/e.total*100); $("#progress").width(percent+"%"); }); return xhr; } ... });

  2. Para las imágenes, necesitas una llamada ajax:

    $.ajax({ method: "GET", url: "http://example.com/path/image.jpg", xhr: function() {/* see the code above*/ } ... });

  3. Para obtener el contenido de un archivo cargado:

    var reader = new FileReader(); reader.readAsText(uploadedFile); $(reader).bind("progress", function(e) { var percent = 0; if (e.lengthComputable) percent = Math.ceil(e.loaded/e.total*100); $("#progress").css("width", percent+"%"); });

  4. Para una gran cantidad de procesos, como matemáticas o agregar muchos divs que tomarán más de 10 segundos:

    Main.js:

    var worker = new Worker("Worker.js"); $(worker).bind("message", function(data) { $("#progress").width((data*100)+"%"); });

    Worker.js:

    var total = 43483, finished = 0, doStuff = function() { ++finished; return 1+1; }; setInterval(function() { self.postMessage(finished/total); }, 100); for (var i = 0; i < total; ++i) setTimeout(doStuff, i*10);

  5. Porque es bueno, y quieres decirle al usuario que hay un progreso cuando no lo hay, simplemente anima el div:

    $("#progress").animate({width: "100%"}, 3000);

Tengo una barra de progreso que actualizo en un bucle de muchas iteraciones.

https://jsfiddle.net/k29qy0do/32/ (abra la consola antes de hacer clic en el botón de inicio)

var progressbar = {}; $(function () { progressbar = { /** initial progress */ progress: 0, /** maximum width of progressbar */ progress_max: 0, /** The inner element of the progressbar (filled box). */ $progress_bar: $(''#progressbar''), /** Set the progressbar */ set: function (num) { if (this.progress_max && num) { this.progress = num / this.progress_max * 100; console.log(''percent: '' + this.progress + ''% - '' + num + ''/'' + this.progress_max); this.$progress_bar.width(String(this.progress) + ''%''); } }, fn_wrap: function (num) { setTimeout(function() { this.set(num); }, 0); } }; }); $(''#start_button'').on(''click'', function () { var iterations = 1000000000; progressbar.progress_max = iterations; var loop = function () { for (var i = 1; i <= iterations; i++) { if (iterations % i === 100) { progressbar.set(i); //only updates the progressbar in the last iteration //progressbar.fn_wrap(i); //even worse, since no output to the console is produced } } } //setTimeout(loop, 0); loop(); });

La consola se actualiza iterativamente como se espera. Sin embargo, la barra de progreso no se está actualizando.

El problema es que la ventana del navegador parece "colgar" hasta que el bucle finaliza. Solo se actualiza la consola, no la barra de progreso.

He intentado agregar el setTimeout, como se sugiere a continuación, en varios lugares. Pero eso solo empeora las cosas, porque entonces ni siquiera hago que la consola muestre el progreso mientras ejecuta el ciclo.


Aquí está el violín actualizado

Utilicé animate para convertirlo en una barra de progreso como la apariencia. Espero que esto te ayudará.

var progressbar = {}; $(function() { progressbar = { /** initial progress */ progress : 0, /** maximum width of progressbar */ progress_max : 0, /** The inner element of the progressbar (filled box). */ $progress_bar : $(''#progressbar''), /** Method to set the progressbar.*/ set : function(num) { if (this.progress_max && num) { this.progress = num / this.progress_max * 100; console.log(''percent: '' + this.progress + ''% - '' + num + ''/'' + this.progress_max); $(''#progressbar'').animate({ width : String(this.progress) + ''%'', }, 500, function() { // Animation complete. }); } }, fn_wrap : function(num) { setTimeout(function() { this.set(num); }, 0); } }; }); $(''#start_button'').on(''click'', function() { $(''#progressbar'').css(''width'', ''0%''); var iterations = 1000000000; progressbar.progress_max = iterations; var loop = function() { for (var i = 1; i <= iterations; i++) { if (iterations % i === 100) { progressbar.set(i); //only updates the progressbar in the last iteration } } } loop(); });

Fiddler

[1]: https://jsfiddle.net/k29qy0do/21/



Estas son mis 2 opiniones sobre la pregunta:

Utilizando un trabajador web . El código de webworker blob viene de here

Código de trabajador web:

<script type="text/ww"> function loop(e) { var data = JSON.parse(e.data); var i = parseInt(data.i, 10); var iterations = parseInt(data.iterations, 10); while (iterations % ++i !== 100 && i <= iterations); if(i <= iterations) { self.postMessage(JSON.stringify({ i: i, iterations: iterations })); } } self.onmessage = function(e) { loop(e); }; </script>

El código:

var ww = document.querySelector(''script[type="text/ww"]''), code = ww.textContent, blob = new Blob([code], {type: ''text/javascript''}), blobUrl = URL.createObjectURL(blob), worker = new Worker(blobUrl); worker.onmessage = function(e) { var data = JSON.parse(e.data); var i = parseInt(data.i, 10); var iterations = parseInt(data.iterations, 10); progressbar.set(i); worker.postMessage(JSON.stringify({ i: i, iterations: iterations })); } $(''#start_button'').on(''click'', function () { var iterations = 1000000000; progressbar.progress_max = iterations; worker.postMessage(JSON.stringify({ i: 0, iterations: iterations })); });

La otra idea cuelga el subproceso de la interfaz de usuario, pero cambia el ancho visualmente, ya que uso requestAnimationFrame para interrumpir el conteo, cambiar el ancho de la barra de progreso y luego continuar el conteo.

function loopFrame(i, iterations) { requestAnimationFrame(function() { if (iterations % i === 100) { progressbar.set(i); } if(i < iterations) { loopFrame(i + 1, iterations); } }); } $(''#start_button'').on(''click'', function () { var iterations = 1000000000; console.log(iterations); progressbar.progress_max = iterations; loopFrame(0, iterations); });


Lo que realmente desea es un bucle asíncrono para permitir que el navegador actualice el DOM entre iteraciones.

JSFiddle: http://jsfiddle.net/u5b6gr1w/

function delayedLoop(collection, delay, callback, context) { context = context || null; var i = 0, nextInteration = function() { if (i === collection.length) { return; } callback.call(context, collection[i], i); i++; setTimeout(nextInteration, delay); }; nextInteration(); }

Algunos HTML:

<div class="progress-bar"><div style="width: 0"></div></div>

Un toque de CSS:

.progress-bar { border: 1px solid black; background-color: #f0f0f0; } .progress-bar div { background-color: red; height: 1.25em; }

Y algunos JavaScript para conectar cosas juntos:

var progressBar = document.querySelector(".progress-bar div"), items = [1,2,3,4,5,6,7,8,9,10]; delayedLoop(items, 500, function(item, index) { var width = (item / items.length * 100) + "%"; progressBar.style.width = width; progressBar.innerHTML = width; });


Puede usar promises para esperar hasta que se establezca el ancho antes de continuar el ciclo.
La actualización de la barra de progreso para 1000000000 iteraciones será lenta si va 1 por 1, por lo que puede resultarle útil disminuir la frecuencia de actualización.
En lugar de un bucle for , utilicé una función recursiva que se repite cuando se cumple la promesa.

set: function (num) { var deferred = $.Deferred(); if (this.progress_max && num) { this.progress = num / this.progress_max * 100; var self = this; self.$progress_bar.animate({"width": String(this.progress) + ''%''}, "fast", function() { deferred.resolve(); }); return deferred; } } $(''#start_button'').on(''click'', function () { var iterations = 1000000000; var i = 0; progressbar.progress_max = iterations; var loop = function(){ i+=100000000; if(i <= iterations){ progressbar.set(i).then(function(){ loop(); }); ; } }; loop(); });

https://jsfiddle.net/k29qy0do/34/


Supongo que todas las actualizaciones de progreso se ejecutan en la misma pila de llamadas. Mientras se ejecuta el código JavaScript, el DOM no se puede actualizar. Tal vez esta question te ayude a encontrar una solución alternativa.


Tal vez esto sea útil.

var service = new Object(); //function with interrupt for show progress of operations service.progressWhile = new Object(); service.progressWhile.dTime = 50; //step ms between callback display function service.progressWhile.i = 0; //index service.progressWhile.timer = 0; //start time for cycle //@parametr arr - array for actions //@parametr actionCallback - The function for processing array''s elements //@parametr progressCallback - function to display the array index function progressWhile(arr, actionCallback, progressCallback) { try { var d = new Date(); service.progressWhile.timer = d.getTime(); log(service.progressWhile.i); if (service.progressWhile.i >= arr.length) { service.progressWhile.i = 0; return; } while (service.progressWhile.i < arr.length) { actionCallback(arr[service.progressWhile.i++]); d = new Date(); if (d.getTime() - service.progressWhile.timer > service.progressWhile.dTime) { break; } } if (progressCallback != undefined) progressCallback(service.progressWhile.i); } catch (er) { log(er); return; } setTimeout(function () { progressWhile(arr, actionCallback, progressCallback); }, 0); }


Vamos a descomponerlo en pasos

Paso 1: Limpiar HTML

Asumir que el propósito de su pregunta es entender cómo trabajar la barra de progreso y no los estilos o las etiquetas (cargando, tenga paciencia, etc.). Solo tenemos la barra de progreso y el botón de inicio.

<div id=''progressbar-outer'' style=""> <div id=''progressbar'' style=""></div> </div> <button id="start_button">Start</button>

Paso 2: Los estilos

Permite hacer visible la barra de progreso para el usuario.

#progressbar-outer { height:2em; border:5px solid #000; width:15em; } #progressbar { width:0%; background-color:#F00; height:100%; }

Paso 3: Usando setTimeout donde pertenece

En su código, ha usado setTimeout para establecer el valor de su barra de progreso. Sin embargo, el bucle for sigue activo.

for (var i = 1; i <= iterations; i++) { if (iterations % i === 100) { progressbar.set(i); //only updates the progressbar in the last iteration //progressbar.fn_wrap(i); //even worse, since no output to the console is produced //setTimeout(function() { // progressbar.set(i); //}, 0); } }

El uso de setTimeout no afecta el resto del código. Por lo tanto, la interfaz de usuario se mantuvo como rehén hasta que el bucle terminó. Prueba el siguiente código.

$(''#start_button'').on(''click'', function () { var iterations = 100; progressbar.progress_max = iterations; var loop = function (value) { progressbar.set(value); if (value < iterations) setTimeout(function () { loop(value + 1) }, 30); else $(''#progressbar'').css(''background-color'', ''#0F0''); } loop(1); });

Avance

Pruebe este violín: https://jsfiddle.net/Ljc3b6rn/4/


window.requestAnimationFrame usar window.requestAnimationFrame , de lo contrario, el navegador se bloqueará hasta que finalice su ciclo. La devolución de llamada pasada a requestAnimationFrame obtendrá una marca de tiempo como un parámetro que podría utilizar para calcular el progreso.