как вызвать функцию после завершения двух разных событий

#javascript #jquery

#javascript #jquery

Вопрос:

Мне нужно инициализировать плагин cropper в модальном всплывающем окне. Всякий раз, когда пользователь нажимает на загрузчик изображений, я хочу показать это изображение во всплывающем окне, и он должен инициализировать плагин cropper, когда модальное всплывающее окно завершает показ анимации, а также после полной загрузки изображения.

В настоящее время происходит то, что когда-то функция инициализации вызывается до загрузки изображения, и когда-то она вызывается правильно. Я хочу вызвать функцию инициализации после загрузки изображения и после изменения $ («#crop-img») src, наконец, он должен проверить, полностью ли загружено модальное всплывающее окно, тогда оно должно запустить функцию инициализации.

оба события непредсказуемы, иногда сначала появляется модальное всплывающее окно, иногда загружается изображение. Я хочу проверить, что событие завершено, а затем должен вызвать initCroping.

Есть ли какой-нибудь простой способ вызвать функцию после завершения этих двух событий.

 $('#cropModel').on('shown.bs.modal', function() {
      //initCroping();

  });


$(".upload").change(function(e){

    var preview = $('#crop-img');
    var file    = document.querySelector('input[type=file]').files[0];
    var reader  = new FileReader();

    reader.addEventListener("load", function () {
      //preview.src = reader.resu<
      $(preview).attr("src",reader.result);
      initCroping();
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }
});
  

Ответ №1:

самый простой метод:

 var counter = 2;
function fireInitCroping() {
    --counter === 0 amp;amp; initCroping();
}

$('#cropModel').on('shown.bs.modal', function() {
      fireInitCroping();
});


$(".upload").change(function(e){

    var preview = $('#crop-img');
    var file    = document.querySelector('input[type=file]').files[0];
    var reader  = new FileReader();

    reader.addEventListener("load", function () {
      //preview.src = reader.resu<
      $(preview).attr("src",reader.result);
      fireInitCroping();
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }
});
  

Ответ №2:

С помощью Screw-FileReader и нескольких обещаний тоже работает

 var shownPopup = new Promise(resolve => 
  $('#cropModel').one('shown.bs.modal', () => resolve())
)

var loadedImage = new Promise((resolve, reject) => {
  $(".upload").change(e => {
    // create a new Image obj from Blob that resolves/reject onload or onerror
    e.target.files[0].image().then(img => {
      img.id = "crop-img"
      $("#crop-img").replaceWith(img)
      resolve()
    } err => {
      console.error('not an image')
      reject(err)
    })
  })
})

// When both event's has fired then fire initCroping
Promise.all([shownPopup, loadedImage]).then(initCroping)