JavaScript加载图像的进度

JS中有一种方式来获取图像加载时的加载图像的进度? 我想使用HTML5的新Progress标签来显示加载图片的进度。

我希望有这样的事情:

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

尝试使用本文中描述的方法还有一个现场示例 。 据我所知,你是在寻找。

用这个,你在Image()对象上添加两个新的函数:

  Image.prototype.load = function(url){ var thisImg = this; var xmlHTTP = new XMLHttpRequest(); xmlHTTP.open('GET', url,true); xmlHTTP.responseType = 'arraybuffer'; xmlHTTP.onload = function(e) { var blob = new Blob([this.response]); thisImg.src = window.URL.createObjectURL(blob); }; xmlHTTP.onprogress = function(e) { thisImg.completedPercentage = parseInt((e.loaded / e.total) * 100); }; xmlHTTP.onloadstart = function() { thisImg.completedPercentage = 0; }; xmlHTTP.send(); }; Image.prototype.completedPercentage = 0; 

在这里你使用加载函数并在div上附加图片。

 var img = new Image(); img.load("url"); document.getElementById("myDiv").appendChild(img); 

在加载状态期间,您可以使用img.completedPercentage检查进度百分比。

塞巴斯蒂安的答案是非常好的,这是我见过的最好的答案。 但是,有一些可能的改进。 我用他的代码修改如下:

 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(); }; 

主要是我添加了一个MIMEtypes和一些小的细节。 用Sebastian描述。 效果很好。

为了增加改进,我修改了Julian的答案(这反过来又修改了Sebastian的答案)。 我已经将逻辑移至一个函数,而不是修改Image对象。 这个函数返回一个Promise ,用URL对象来parsing,只需要作为image标签的src属性插入。

 /** * 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" /> 

其实,在最新的铬可以使用它。

 $progress = document.querySelector('#progress'); var url = 'https://placekitten.com/g/2000/2000'; var request = new XMLHttpRequest(); request.onprogress = onProgress; request.onload = onComplete; request.onerror = onError; function onProgress(event) { if (!event.lengthComputable) { return; } var loaded = event.loaded; var total = event.total; var progress = (loaded / total).toFixed(2); $progress.textContent = 'Loading... ' + parseInt(progress * 100) + ' %'; console.log(progress); } function onComplete(event) { var $img = document.createElement('img'); $img.setAttribute('src', url); $progress.appendChild($img); console.log('complete', url); } function onError(event) { console.log('error'); } $progress.addEventListener('click', function() { request.open('GET', url, true); request.overrideMimeType('text/plain; charset=x-user-defined'); request.send(null); }); 
 <div id="progress">Click me to load</div> 

对于xmlhttpreq v2检查,请使用:

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

下面是Julian Jensen代码的一个小的更新,以便能够在加载后在Canvas中绘制图像:

 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 ); }; }; 

如果你想处理你加载的图像,比你必须添加一个更多的function,因为

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

只是开始处理图像作为一个线程。

你必须添加一个新的function到负载原型的身体,就像

  this.onload = function(e) { var canvas = document.createElement('canvas') canvas.width = this.width canvas.height = this.height canvas.getContext('2d').drawImage(this, 0, 0) } 

这让我很头疼实现:)