Display how many kilobytes are remaining to download

Can JavaScript be used to display the remaining file size (in kb) needed to fully download a gif file from a remote server?

    function downgif(id, img){
    //show downloading
    Show('downloadgif');
    
    //change image
    document.getElementById(id).src=img;
   
   //test if complete
    var completeInterval = null, renderedInterval = null, count = 0;
    var theImg = document.getElementById(id);
    theImg.src = img;
    // Wait for image to be loaded (but not necessarily rendered)
    completeInterval = setInterval(function() {
      if (theImg.complete) {
        // Cancel checking once IMG is loaded OR we've tried for ~9s already
        clearInterval(completeInterval);
        completeInterval = null;
          // IMG is now 'complete' - but that just means it's in the render queue...
          // Wait for naturalWidth and naturalHeight to be > 0 since this shows
          // that the image is done being RENDERED (not just 'loaded/complete')
          renderedInterval = setInterval(function() {
            if (theImg.naturalHeight > 0 && theImg.naturalWidth > 0) {
              clearInterval(renderedInterval);
              renderedInterval = null;

              //hide downloading
              Hide('downloadgif');
            }
          }, 100);
      }
    }, 450);
 
}

Answer №1

A demonstration of tracking the progress of downloading a GIF file from a remote server can be achieved by utilizing either the XMLHttpRequest or Fetch API, instead of a traditional <img /> tag.

Using XMLHttpRequest

The XMLHttpRequest object offers an onprogress event that can be leveraged to monitor the download progress.

function downgif(url, imgElementId) {
    const xhr = new XMLHttpRequest();
    const imgElement = document.getElementById(imgElementId);

    xhr.open('GET', url, true);
    xhr.responseType = 'blob';

    xhr.onprogress = function(event) {
          const kbRemaining = ((event.total - event.loaded) / 1024).toFixed(2);
          console.log(`Remaining: ${kbRemaining} KB`);
    };

    xhr.onload = function() {
          const blobUrl = URL.createObjectURL(xhr.response);
          imgElement.src = blobUrl;
          console.log("Download complete.");
    };

    xhr.send();
}

const url = "https://example.com/your-gif.gif";
downgif(url, 'gifDisplay');
<img id="gifDisplay">

Using Fetch

The Fetch API enables downloading a resource as a stream and allows calculating progress based on the Content-Length header.

async function downgif(url, imgElementId) {
    const imgElement = document.getElementById(imgElementId);
    const response = await fetch(url);
    
    const contentLength = response.headers.get('Content-Length');
    
    const total = parseInt(contentLength, 10);
    let loaded = 0;

    const reader = response.body.getReader();
    const chunks = [];
    while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        chunks.push(value);
        loaded += value.length;

        const kbRemaining = ((total - loaded) / 1024).toFixed(2);

        console.log(`Remaining: ${kbRemaining} KB`);
    }


    const blob = new Blob(chunks);
    const blobUrl = URL.createObjectURL(blob);
    imgElement.src = blobUrl;

    console.log("Download complete.");
}

const url = "https://example.com/your-gif.gif";
downgif(url, 'gifDisplay');
<img id="gifDisplay">

To try this functionality with other large GIF files, you can explore various examples available on Wikipedia's category page for animated GIFs (the demo GIF in this example is sourced from there).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Step-by-step guide to start an AngularJs application using TypeScript

I have developed an AngularJS App using TypeScript The main app where I initialize the App: module MainApp { export class App { public static Module : ng.IModule = angular.module("mainApp", []) } } And my controller: module MainApp { exp ...

Issue with Bootstrap Collapse functionality, functional in JSFiddle but not in actual application

I recently delved into using bootstrap and encountered a problem while trying to implement the "Collapse" feature. I am confident that I have correctly linked the Javascript file, as the CSS reference is working fine. I even attempted to switch to using t ...

Webpack loaders or plugins: understanding the distinction

Can you explain the distinction between loaders and plugins in webpack? I found on the documentation for plugins that it states: Plugins are used to incorporate extra functionalities usually related to bundles within webpack. While I understand that b ...

Obtaining a webpage link from a div element with JQuery

I have been working on developing my own lightbox gallery and I think I'm almost there. My gallery is currently set up as a grid, where each cell displays a preview image using an img tag with the url specified in the CSS. However, if I can't ex ...

Automatically bind model in Asp.Net MVC 4 by utilizing an array of objects in form submission

I have created an array of objects in JavaScript and need to send them back to the server using Ajax (jQuery is being used) This is how the object array looks like in JavaScript: var columns = [ { name: 'col 1', source: 'whatever' ...

Transforming a jQuery trigger into vanilla JavaScript

Can anyone assist me in converting a trigger from jquery to pure javascript when clicked? The code is as follows: $("#classone").click(function () { $("li").toggleClass("visible"); }); ...

What is the best way to find the product of each object in an array by the corresponding values in another array?

Searching for a solution to an issue I encountered while working on an assignment. The problem can be illustrated as follows: var arrOfObj = [{a:10 },{a:20},{a:30}, ......] var arrToMultiply = [2,4,6, .....] The expected result const result = [{a:10,resul ...

Tips for creating a stylish scrollbar in a React Material-Table interface

Currently, I am utilizing the react material-table and looking to implement a more visually appealing scroll-bar instead of the default Pagination option. Although I have experimented with the react-custom-scroll package, it has not produced the desired ...

Efficiently compare arrays, eliminate identified keys in the second array

Two arrays are given, and the resulting unmatched array contains duplicates that need to be eliminated. This will result in the countB variable being smaller once all duplicates are removed from the unmatched array. const arr1 = ['Bill', &apo ...

Using jQuery to retrieve the id with [id^=''] when making an AJAX request, then populating and generating a table based on the retrieved data

In my jQuery code, I am using AJAX to fetch data and then creating a simple table with that data. Here is an example: $.ajax({ method: 'GET', url: '/analyzePage/searchTag/' + tagName, contentType: false, processData: fa ...

Samsung browser encounters an international error

After developing my web application using Angular2 Rc1, I noticed that it functions perfectly on Safari, Firefox, and Chrome browsers. However, when trying to access the application on my Galaxy S6 using the default browser, an error pops up: https://i.s ...

Is there an issue with this code? HTML5 canvas

I am attempting to create a mesmerizing animation of a black hole simulation using the canvas element. My goal is to make objects exit the black hole if their distance from its center is greater than the black hole's radius, and to do so at variable s ...

What sets array of middlewares apart from compose-middleware?

Someone recommended that I utilize the compose-middleware module in order to have an array of middlewares. After trying it out, I discovered that it works seamlessly with express.js: router.post('/editPassword', doAction ); var doAction = [ ...

Updating multiple documents in Mongoose that have a specific element in an array

I have structured a Mongoose schema like this: const mongoose = require('mongoose'); const ItemSchema = mongoose.Schema({ id: { type: String, required: true, }, items: { type: Array, required: true, }, date: { type: ...

Unable to trigger onclick event for creating a new title

I'm currently working on a text generator project using JavaScript. My goal is to create a function that saves the selected text from a dropdown menu and displays it as the page title when the "Generate" button is clicked. The issue I'm facing i ...

SecurityError: The dubious operation triggers CORS to persist in its insecurities

I have developed an HTTP server using Express in Node.js. This server is currently running locally on port 3000. There is a served HTML page called "index.html" which makes AJAX GET requests for contents (in HTML format). These AJAX contents are also serv ...

Catalog indexed in a JSON document

I'm currently facing an issue with extracting data from a JSON file and populating a list with that information. HTML : <ol id="dataT"> </ol> JavaScript : function GetData(index) { var xhttp = new XMLHttpRequest(); xhttp.onre ...

Activate or deactivate a button depending on the input value of a TextField in React.js

I am currently designing a form similar to the one displayed in this image. I want the "Add" button to become active as soon as the user starts typing in the "Tags" input field. For this project, I am using material-ui and I have created an Input compone ...

When clicking on the side-bar, it does not respond as expected

My website has a menu layout that features a logo on the left and an icon for the menu on the right side. When the icon is clicked, the menu slides in from the right side of the window, and when clicked again, it slides out. However, I am facing two issues ...

Is there a way for me to pinpoint the location of an error in React?

Currently, I am operating a basic React application with webpack in development mode by using the following command: webpack -w --mode development --config ./webpack.config.js This setup ensures that my code remains unminified. However, I am encounterin ...