这看起来像是一个重复的问题,但我向你保证不会。
我从服务器端servlet提供的AJAX调用中加载了几个动态图像。我需要将图像分成三部分,但在图像加载之前我不能这样做。这让我想到了我的问题。我为每个图像都有一个onload触发器,但它在图像属性可用之前触发(例如高度,宽度等)。所以我的代码无法进行错误处理。
var imageData = [];
$( document ).ready(function() {
preLoadImages();
});
function preLoadImages() {
<c:forEach var="table" items="${tables}">
var tmpImage = new imageObject(<c:out value="${table.tableRowId}" />);
imageData.push(tmpImage);
</c:forEach>
for (var i = 0; i < imageData.length; i++) {
ajaxGetmainImages(i);
}
}
function imageObject(id) {
this.id = id;
this.mainImage = new Image();
this.topImage = new Image();
this.middleImage = new Image();
this.bottomImage = new Image();
}
function split_3(i) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
if (imageData[i].mainImage.height > 2500) {
$("#error_container-" + imageData[i].id).attr('display', "none");
//document.getElementById('error_container').style.display = "none";
var newWidth = imageData[i].mainImage.width;
var newHeight = imageData[i].mainImage.height / 3;
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(imageData[i].mainImage, 0, 0, newWidth, newHeight, 0, 0, newWidth, newHeight);
imageData[i].topImage.src = canvas.toDataURL();
ctx.drawImage(imageData[i].mainImage, 0, (newHeight), newWidth, newHeight, 0, 0, newWidth, newHeight);
imageData[i].middleImage.src = canvas.toDataURL();
ctx.drawImage(imageData[i].mainImage, 0, ((newHeight * 2)), newWidth, newHeight, 0, 0, newWidth, newHeight);
imageData[i].bottomImage.src = canvas.toDataURL();
$("#left_image-" + imageData[i].id).attr('src', imageData[i].topImage.src);
$("#right_image-" + imageData[i].id).attr('src', imageData[i].bottomImage.src);
}
else {
$("#slider_container-" + imageData[i].id).attr('display', "none");
$("#error_image-" + imageData[i].id).attr('src', imageData[i].mainImage.src);
}
}
function ajaxGetmainImages(i)
{
$.ajax({
type: "GET",
url: baseURL + '/admin/' + imageData[i].id,
dataType: "json",
async: true,
success:function(data){
imageData[i].mainImage.onload = split_3(i);
imageData[i].mainImage.src = "data:image/jpg;base64," + data.image;
//imageData[i].mainImage.addEventListener("load", split_3(i));
},
error:function(result){
//$("#" + id + 'status').html("<img src='../resources/img/status-unknown-16.png' alt='Unknown'>");
}
});
}
图像ID是通过提供页面的servlet中的模型提供的。有了这个,我构建了唯一的URL来轮询每个图像。这段代码有效。我让它在一个单独的页面中运行,我只处理单个图像(图像被分割,以便可以使用滑块来比较图像)。但是,当我尝试使用多个图像时,在onload功能期间图像的高度始终为0。如果我在split_3函数中设置断点,我可以看到当处理 next 图像时,前一个图像现在具有非零高度值(正确的值)。
我尝试过Chrome Stable,Chrome Beta,Chrome Dev,Firefox和Opera,结果都是一样的。 onload似乎太早引发了一点,我不明白为什么。
编辑:一些额外的信息。图像最终加载。如果服务器端代码无法获取正确的图像,则它会提供默认占位符(因此else&gt;&#34; error_image&#34;)。但占位符不需要拆分。所以我在我的页面上得到的是错误占位符中的整个3倍高度图像。这是最终的问题。
答案 0 :(得分:2)
addEventListener
的参数必须是对函数的引用。您立即调用该函数并将结果传递给addEventListener
。它应该是:
imageData[i].mainImage.addEventListener("load", function() {
split_3(i));
});
或onload
:
imageData[i].onload = function() { split_3(i); };
答案 1 :(得分:1)
感谢所有回复的人。我发现了这个问题。问题是我正在调用onload方法:
tableData[i].tableImage.onload = split_3(i);
立即调用它,因为它不是引用。我修改了以下代码。
tableData[i].tableImage.indexId = i;
tableData[i].tableImage.onload = split_3;
tableData[i].tableImage.src = "data:image/jpg;base64," + data.image;
我还将当前索引存储在图像对象本身中。这样我可以在触发onload时回调它。
function split_3() {
var i = this.indexId;
其余代码无需任何更改即可运行。