我有一个需要在提交时加载图片像素的表单。我注意到的问题是表单是在图像加载之前提交的。我想在提交表单之前等待图片加载。我还需要保持这种模块化,以便它可以在同一页面上用于多个图像和多个表单。
function loadImgPixel(pixelSrc){
//the image pixel simply needs to load, not be displayed so there is no need to append this to the body element
$("<img />").attr("src",pixelSrc).on("load",function(){
return true;
})
}
$("#myform").submit(function(e){
e.preventDefault();
form = $(this);
var pix1 = loadPixel("https://cdn4.iconfinder.com/data/icons/sports-balls/1024/BasketBall.png");
var pix2 = loadPixel("https://cdn4.iconfinder.com/data/icons/sports-balls/128/Tennis_ball.png");
if(pix1 && pix2){
form.unbind("submit") //unbind submit so there isn't an endless loop due to 'preventDefault'
.submit(); //submit form;
}
})
当我在alert
函数上执行loadImgPixel(pixelSrc)
时。它会抛出undefined
。似乎它试图在.on("load")
实际return true
之前看到返回值。
问题#2:代码段的.unbind
部分用于防止可能导致code here的循环。然而,当我解除并立即提交后,没有任何反应。
奖励积分:让我说我需要在表单提交上加载30个像素,这是确保在提交表单之前加载所有内容的最有效方法。我想有一种更好的检查方法,而不仅仅是(pix1 && pix2 && pix3 $$ pix4....){}
答案 0 :(得分:1)
.load
event of theimage-element
is asynchronous in nature. You can not be certain whensrc
of the element will be loaded.
To handle such asynchronous
activities, we can use callback
or Promise
要确定所有承诺已完成,fulfilled
或rejected
,我们会使用Promise.all(iterable)
方法。
resolve
的结果作为所有承诺的值数组传递。为了测试所有resolved
值是否通过某个测试,我们可以使用Array#every
,every()
方法测试数组中的所有元素是否都通过了由提供的函数实现的测试。
function loadPixel(pixelSrc) {
return new Promise(function(resolve, reject) {
$("<img />").attr("src", pixelSrc).on("load", function() {
resolve(true);
}).on('error', function() {
reject();
});
});
}
$("#myform").submit(function(e) {
e.preventDefault();
var form = $(this);
var pix1 = loadPixel("https://cdn4.iconfinder.com/data/icons/sports-balls/1024/BasketBall.png");
var pix2 = loadPixel("https://cdn4.iconfinder.com/data/icons/sports-balls/128/Tennis_ball.png");
Promise.all([pix1, pix2]).then(function(values) {
var res = values.every(Boolean);
if (res) {
form.unbind("submit").submit();
}
}, function(reason) {
console.log(reason);
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form action="" id='myform'>
<input type="submit">
</form>