Ajax Binario (parte 2 con barra de progreso)

13-4-2020

Ya vimos cómo se puede subir y mostrar una imagen usando ajax.

Pero cómo podríamos agregar una barra de progreso o progress bar que nos indique cuánto hemos cargado el archivo y cuánto falta?

He aquí un ejemplo.

//Ya teníamos nuestro ejemplo en html, ahora vamos a agregarle la barra de progreso

    <form>
        <input type="file">
        <button>Enviar</button>
    </form>
    <hr>
    <progress min="0" max="100" value="0"></progress> <span></span>
    <br><br>
    <img src="" alt="">

    <script src="js/main.js"></script>

 

Y ahora vamos a trabajar sobre esta barra.

El ejemplo es muy similar al anterior, pero agregamos la barra de progreso.

//vamos a modificar la función que trae la imagen

function cargarImagen(imagen) {
    let img = document.querySelector('img')
    //esta vez metemos en una variable la barra de progreso también
    let progress = document.querySelector('progress')
    //y el span vacío que pusimos al lado de la barra de progreso en nuestro html, para que además de mostrarlo en la barra nos diga el porcentaje de subida
    let span = document.querySelector('span')
    //la imagen vuelve a comenzar vacía
    img.src = ''
    //y el valor de la barra de progreso en cero
    progress.value = 0
    //y, justamente ponemos cero por ciento al lado
    span.innerHTML = '0%'

    //el resto del código para trabajar la imagen es similar...
    let xhr = new XMLHttpRequest
    xhr.responseType = 'blob'
    
    let urlSinCache = imagen + '?' + Date.now()
    console.log(urlSinCache)

    xhr.open('get', urlSinCache)
    xhr.addEventListener('load', () => {
        if(xhr.status == 200) {
            let imagenBlob = xhr.response
            console.log(imagenBlob)
            let url = URL.createObjectURL(imagenBlob)
            console.log(url)

            /*
            let img = document.createElement('img')
            img.src = url
            document.body.appendChild(img)
            */
           img.src = url
        }
    })

    xhr.addEventListener('progress', e => {
/*
       el evento nos permite hacer el cálculo, tomando las propiedades de 
       dicho objeto e que necesitamos: 
       lengthComputable -- nos sirve para saber si la imagen tiene un peso dado, para hacer el trabajo sólo si lo tiene
       loaded -- es la cantidad que se descargó al momento
       total -- es el total del peso de la imagen
*/
        if(e.lengthComputable) {
            //aquí ya es sólo sacar el porcentaje que sobre el total se ha descargado
            let porcentaje = parseInt((e.loaded * 100) / e.total)
            //console.log(porcentaje + '%')
            //en valor vamos cambiando la cantidad
            progress.value = porcentaje
            //y vamos agregando el porcentaje al span en 0% que teníamos al principio
            span.innerHTML = porcentaje + '%'
        }
    })
    //Y NO OLVIDARSE DE ENVIAR EL PEDIDO, SINO NO ANDA
    xhr.send()
}

//el escuchador del form es similar al anterior
let form = document.querySelector('form')
form.addEventListener('submit', e => {
    e.preventDefault()
    let archivo = form[0].files[0].name
    cargarImagen(archivo)
})