javascript - span - window title js




Выполнение загрузки изображения JavaScript (6)

Есть ли способ в JS для получения прогресса загрузочного изображения во время загрузки изображения? Я хочу использовать новый тег Progress HTML HTML5, чтобы показать ход загрузки изображений.

Хотелось бы что-то вроде:

var someImage = new Image()
someImage.onloadprogress = function(e) { progressBar.value = e.loaded / e.total };
someImage.src = "image.jpg";

Вот небольшое обновление кода Юлиана Дженсена, чтобы иметь возможность рисовать изображение на холсте после его загрузки:

xmlHTTP.onload = function( e ) {
        var h = xmlHTTP.getAllResponseHeaders(),
            m = h.match( /^Content-Type\:\s*(.*?)$/mi ),
            mimeType = m[ 1 ] || 'image/png';
            // Remove your progress bar or whatever here. Load is done.

        var blob = new Blob( [ this.response ], { type: mimeType } );
        thisImg.src = window.URL.createObjectURL( blob );

         thisImg.onload = function()
            {
                if ( callback ) callback( this );
            };
    };

Если вы хотите обработать загруженное изображение, вам нужно добавить еще одну функцию, потому что

thisImg.src = window.URL.createObjectURL(blob)

просто начинает обрабатывать изображение как поток.

Вы должны добавить новую функцию в тело прототипа нагрузки, например

  this.onload = function(e)
  {
    var canvas = document.createElement('canvas')

    canvas.width = this.width
    canvas.height = this.height

    canvas.getContext('2d').drawImage(this, 0, 0)
   }

Это делает мне головную боль, чтобы понять :)


Ответ Себастьяна превосходный, лучшее, что я видел на этот вопрос. Однако есть несколько возможных улучшений. Я использую его код, модифицированный следующим образом:

Image.prototype.load = function( url, callback ) {
    var thisImg = this,
        xmlHTTP = new XMLHttpRequest();

    thisImg.completedPercentage = 0;

    xmlHTTP.open( 'GET', url , true );
    xmlHTTP.responseType = 'arraybuffer';

    xmlHTTP.onload = function( e ) {
        var h = xmlHTTP.getAllResponseHeaders(),
            m = h.match( /^Content-Type\:\s*(.*?)$/mi ),
            mimeType = m[ 1 ] || 'image/png';
            // Remove your progress bar or whatever here. Load is done.

        var blob = new Blob( [ this.response ], { type: mimeType } );
        thisImg.src = window.URL.createObjectURL( blob );
        if ( callback ) callback( this );
    };

    xmlHTTP.onprogress = function( e ) {
        if ( e.lengthComputable )
            thisImg.completedPercentage = parseInt( ( e.loaded / e.total ) * 100 );
        // Update your progress bar here. Make sure to check if the progress value
        // has changed to avoid spamming the DOM.
        // Something like: 
        // if ( prevValue != thisImage completedPercentage ) display_progress();
    };

    xmlHTTP.onloadstart = function() {
        // Display your progress bar here, starting at 0
        thisImg.completedPercentage = 0;
    };

    xmlHTTP.onloadend = function() {
        // You can also remove your progress bar here, if you like.
        thisImg.completedPercentage = 100;
    }

    xmlHTTP.send();
};

В основном я добавил mime-тип и некоторые мелкие детали. Использование, как описывает Себастьян. Работает хорошо.



Чтобы добавить к улучшениям, я изменил ответ Джулиана (который, в свою очередь, изменил Себастьяна). Я переместил логику в функцию вместо изменения объекта Image . Эта функция возвращает Promise которая разрешает объект URL, который нужно только вставить как атрибут src тега image .

/**
 * Loads an image with progress callback.
 *
 * The `onprogress` callback will be called by XMLHttpRequest's onprogress
 * event, and will receive the loading progress ratio as an whole number.
 * However, if it's not possible to compute the progress ratio, `onprogress`
 * will be called only once passing -1 as progress value. This is useful to,
 * for example, change the progress animation to an undefined animation.
 *
 * @param  {string}   imageUrl   The image to load
 * @param  {Function} onprogress
 * @return {Promise}
 */
function loadImage(imageUrl, onprogress) {
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    var notifiedNotComputable = false;

    xhr.open('GET', imageUrl, true);
    xhr.responseType = 'arraybuffer';

    xhr.onprogress = function(ev) {
        if (ev.lengthComputable) {
          onprogress(parseInt((ev.loaded / ev.total) * 100));
        } else {
          if (!notifiedNotComputable) {
            notifiedNotComputable = true;
            onprogress(-1);
          }
        }
    }

    xhr.onloadend = function() {
      if (!xhr.status.toString().match(/^2/)) {
        reject(xhr);
      } else {
        if (!notifiedNotComputable) {
          onprogress(100);
        }

        var options = {}
        var headers = xhr.getAllResponseHeaders();
        var m = headers.match(/^Content-Type\:\s*(.*?)$/mi);

        if (m && m[1]) {
          options.type = m[1];
        }

        var blob = new Blob([this.response], options);

        resolve(window.URL.createObjectURL(blob));
      }
    }

    xhr.send();
  });
}

/*****************
 * Example usage
 */

var imgContainer = document.getElementById("imgcont");
var progressBar = document.getElementById("progress");
var imageUrl = "https://placekitten.com/g/2000/2000";

loadImage(imageUrl, (ratio) => {
  if (ratio == -1) {
    // Ratio not computable. Let's make this bar an undefined one.
    // Remember that since ratio isn't computable, calling this function
    // makes no further sense, so it won't be called again.
    progressBar.removeAttribute("value");
  } else {
    // We have progress ratio; update the bar.
    progressBar.value = ratio;
  }
})
.then(imgSrc => {
  // Loading successfuly complete; set the image and probably do other stuff.
  imgContainer.src = imgSrc;
}, xhr => {
  // An error occured. We have the XHR object to see what happened.
});
<progress id="progress" value="0" max="100" style="width: 100%;"></progress>

<img id="imgcont" />


для проверки xmlhttpreq v2 используйте:

var xmlHTTP = new XMLHttpRequest();
if ('onprogress' in xmlHTTP) {
 // supported 
} else {
 // isn't supported
}




progress