我正在Javascript中构建照片上传器并阅读已上传的照片我已经使用此代码:
// Populate with existing photos
var index;
for (index = 0; index < params.photosToPopulate.length; ++index) {
// Get the data of the image
getDataUri(params.photosToPopulate[index], params, function(dataURI){
// Get the Blob
dataURItoBlob(dataURI, function(dataurl){
var blob = URL.createObjectURL(dataurl);
// fileItem
var fileItem = document.createElement("div");
fileItem.setAttribute('angle', 0);
fileItem.setAttribute('blob', blob);
fileItem.className = 'imageloaderplusFile';
filesdiv.appendChild(fileItem);
// fileImg
var fileImg = document.createElement("div");
fileImg.className = 'imageloaderplusImage';
fileImg.style.backgroundImage = 'url(' + dataURI + ')';
fileItem.appendChild(fileImg);
// fileRotate
var fileRotate = document.createElement("div");
fileRotate.className = 'imageloaderRotate';
fileRotate.setAttribute('title', 'Rotate');
fileItem.appendChild(fileRotate);
fileRotate.onclick = function(){
var angle;
switch(parseInt(this.parentNode.getAttribute('angle'))){
case 0:
angle = 90;
break;
case 90:
angle = 180;
break;
case 180:
angle = 270;
break;
case 270:
angle = 0;
break;
}
this.parentNode.setAttribute('angle', angle);
// css
var image = this.parentNode.firstChild;
image.style.webkitTransform = 'rotate(' + angle + 'deg)';
image.style.mozTransform = 'rotate(' + angle + 'deg)';
image.style.msTransform = 'rotate(' + angle + 'deg)';
image.style.oTransform = 'rotate(' + angle + 'deg)';
image.style.transform = 'rotate(' + angle + 'deg)';
// draw
ImageLoaderPlus.draw(this.parentNode, params);
}
// fileRemove
var fileRemove = document.createElement("div");
fileRemove.className = 'imageloaderRemove';
fileRemove.setAttribute('title', 'Remove');
fileItem.appendChild(fileRemove);
fileRemove.onclick = function(){
this.parentNode.parentNode.removeChild(this.parentNode);
}
// draw
ImageLoaderPlus.draw(fileItem, params);
});
});
} // End For Loop
在For循环中我已经订购了照片,但有时由于异步函数getDataUri()和dataURItoBlob(),For循环中项目的顺序不会转换为de UI / DOM中的顺序照片显示的顺序不正确。我怎样才能防止这种情况发生?
异步函数是这样的:
function getDataUri(url, params, callback) {
var image = new Image();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
//image.crossOrigin = "anonymous"; // This enables CORS
// get scale
var scale = (params.resize && (image.width > params.maxWidth || image.height > params.maxHeight)) ? Math.min(params.maxWidth / image.width, params.maxHeight / image.height) : 1;
image.onload = function (event) {
try {
canvas.width = Math.round(image.width * scale);
canvas.height = Math.round(image.height * scale);
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
//console.log( ctx.canvas.toDataURL('image/jpeg', params.jpegQuality) );
result = ctx.canvas.toDataURL('image/jpeg', params.jpegQuality)
callback(result);
} catch (e) {
alert(e);
}
};
image.src = url;
}
// To convert URL to Blob
function dataURItoBlob(dataURI, callback) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(dataURI.split(',')[1]);
} else {
byteString = unescape(dataURI.split(',')[1]);
}
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
try {
result = new Blob([ab], {type: mimeString});
//return new Blob([ab], {type: mimeString});
} catch (e) {
// The BlobBuilder API has been deprecated in favour of Blob, but older
// browsers don't know about the Blob constructor
// IE10 also supports BlobBuilder, but since the `Blob` constructor
// also works, there's no need to add `MSBlobBuilder`.
var BlobBuilder = window.WebKitBlobBuilder || window.MozBlobBuilder;
var bb = new BlobBuilder();
bb.append(ab);
result = bb.getBlob(mimeString);
//return bb.getBlob(mimeString);
}
callback(result);
}
有关如何避免此问题的任何线索?
最诚挚的问候,
答案 0 :(得分:1)
您可以通过在接收数据时将dataurl
值存储在数组中来解决此问题,但是在该数组中的正确索引处。然后当你计算出你收到了所有dataurl
个值时,就会对该数组执行循环并像现在一样执行元素创建代码。
// Intermediate array to store the dataURI and dataurl values in order
var urls = [];
var URIs = [];
// Keep count of how many dataurl values we received
var leftOver = params.photosToPopulate.length;
// Iterate in a way that you create a new closure on every iteration,
// each iteration has its proper index variable
params.photosToPopulate.forEach(function (photo, index) {
// Get the data of the image
getDataUri(photo, params, function(dataURI){
// Store at the right place in our array
URIs[index] = dataURI;
// Get the Blob
dataURItoBlob(dataURI, function(dataurl){
// Only store the url at the right place in our array
urls[index] = dataurl;
// ... and update the count
leftOver--;
// All done? Then iterate over the dataurl values in the correct order
if (!leftOver) urls.forEach(function(dataurl, index) {
var dataURI = URIs[index]; // get correct dataURI
var blob = URL.createObjectURL(dataurl);
// fileItem
var fileItem = document.createElement("div");
// ...etc, all your element creation code comes here, unchanged.
// ...
// draw
ImageLoaderPlus.draw(fileItem, params);
});
});
});
});