在图像像素加载时提交表单

Submit form on Image pixel load

我有一个表单需要在提交时加载图像像素。我注意到的问题是,在图像加载之前提交了表单。我想在提交表单之前等待图像加载。我还需要保持这个模块化,以便它可以用于同一页面上的多个图像和多个表单。

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

})  

当我在 loadImgPixel(pixelSrc) 函数上执行 alert 时。它返回 undefined。它似乎试图在 .on("load") 实际 return true.

之前查看 return 值

问题#2:代码段的 .unbind 部分用于防止可能像 code here 一样引起的循环。但是当我解除绑定并立即提交时,没有任何反应。

奖励积分:假设我需要在表单提交时加载 30 像素,什么是确保在提交表单之前加载所有像素的最有效方法。我想有比 if(pix1 && pix2 && pix3 $$ pix4....){}

更好的检查方法

.load event of the image-element is asynchronous in nature. You can not be certain when src of the element will be loaded.

要处理此类 asynchronous 活动,我们可以使用 callbackPromise

The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.

为了确定所有承诺都完成fulfilledrejected,我们使用Promise.all(iterable)方法。

resolve 的结果作为所有承诺的值数组传递。为了测试是否所有的resolved值都通过了某个测试,我们可以使用Array#everyevery()方法测试数组中的所有元素是否通过提供的函数实现的测试。

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>

Fiddle Demo