Функция Javascript img.onload ничего не возвращает (истина или ложь)

function getMeta() {
  var img = new Image();
  var verif = true;
  img.onload = function() {
    if (this.width != 468 && this.height != 60) {
      alert('error : only these image sizes are accepted : 468x60');
      return false;
    } else
      alert('loaded successfully');
  };
  img.onerror = function() {
    alert('error : this is not a valid image');
    return false;
  };
  img.src = document.getElementById('t1').value;
  return true;
}
<form action="https://www.paypal.com/cgi-bin/webscr" 
      method="post" target="_blank" id="form1" 
      onsubmit="return getMeta();">

функция img.onload ничего не вернет. Мне нужно возвращаемое значение true или false.

Я хочу использовать возвращаемое значение при отправке формы. кто-нибудь может мне помочь?


person king bla    schedule 24.04.2016    source источник
comment
.onload является асинхронным, что означает, что он вызывается системой когда-то в будущем, и любое значение, которое вы возвращаете из него, просто возвращается в систему, а не в ваш собственный код.   -  person jfriend00    schedule 24.04.2016
comment
Я пытался использовать обратный вызов, но он у меня не работает... однако мне просто нужно решение для моего кода. если бы вы могли мне помочь, я буду признателен. Благодарность   -  person king bla    schedule 24.04.2016
comment
@Oriol - это НЕ прямая копия этого сообщения, потому что в этом сообщении НЕ описывается, как решить эту конкретную проблему. Да, в нем описывается, почему вы не можете вернуть результаты асинхронного обратного вызова с помощью обратных вызовов или промисов, но не объясняется, как применить решение к асинхронной отправке формы. Первоначально я пометил это как дубликат этого, а затем, после дальнейшего комментария, ОП понял, что этот другой ответ НЕ объясняет, как решить эту проблему, поэтому я снова открыл его. Вы должны снова открыться. Этот другой пост не даст полного ответа на этот ОП.   -  person jfriend00    schedule 24.04.2016
comment
@jfriend00 Именно это я и хотел сказать, спасибо   -  person king bla    schedule 24.04.2016
comment
Пожалуйста, не отмечайте это как дубликат Как мне вернуть ответ на асинхронный вызов. Он уже дважды был помечен как дубликат, а затем каждый раз открывался заново, потому что в этом сообщении не описывается, как на самом деле решить проблему отправки асинхронной формы здесь. Это помогает понять, почему возникла проблема, но не дает фактического решения этой проблемы.   -  person jfriend00    schedule 24.04.2016


Ответы (1)


Для общего ознакомления вы должны прочитать Как мне вернуться ответ от асинхронного вызова?. Это описывает общую проблему получения асинхронного результата. Прочитав это, вы, надеюсь, поймете, почему нельзя просто вернуть значение из .onload() и ожидать, что это будет возвращаемое значение из getMeta(). Но этот ответ сам по себе не предлагает полного решения вашей конкретной проблемы.

Итак, теперь давайте немного подробнее опишем, что происходит в вашем коде, а затем обсудим вариант исправления.

img.onload является асинхронным. Это означает, что он когда-то заканчивается, спустя много времени после того, как getMeta() уже вернулся.

Между тем, вы пытаетесь сделать это:

onsubmit="return getMeta();"

Это выглядит так, как будто вы пытаетесь использовать асинхронный результат, чтобы определить, должна ли форма отправляться или нет. Это просто не может быть сделано таким образом. Асинхронный результат еще не известен, и ваша функция getMeta() всегда возвращает true.

Вы можете реструктурировать свой код, чтобы он никогда не отправлялся синхронно. Вы загружаете изображение, и только когда изображение загружается, вы либо показываете ошибку пользователю, либо вручную отправляете форму. У этого есть потенциальные проблемы с пользовательским интерфейсом, потому что пользователь нажимает кнопку отправки, и ничего не происходит немедленно (потому что вы загружаете изображение для проверки). Это заставляет пользователя задуматься о том, что происходит. Они часто думают, что это не сработало, и либо снова нажимают кнопку отправки, либо думают, что это просто сломано. Таким образом, вам обычно требуется куча пользовательского интерфейса вокруг этого, чтобы отключить кнопку, предоставить обратную связь о том, что вы проверяете изображение сейчас, а затем предоставить соответствующее сообщение об ошибке, если изображение не проверяется, и часто другие элементы пользовательского интерфейса должны быть отключены, пока вы вы проверяете изображение, чтобы пользователь не отвлекался и не занимался другими делами, пока вы пытаетесь решить, собираетесь ли вы отправить эту форму или нет.

Итак, чтобы исправить отправку:

В вашем обработчике onsubmit вы всегда будете возвращать false, чтобы форма никогда не отправлялась немедленно. Затем в обработчике onload() (после загрузки изображения) вы вручную отправляете форму или показываете ошибку.

person jfriend00    schedule 24.04.2016
comment
@Oriol - Если вы голосуете против, пожалуйста, передумайте. Сообщение, которое вы отметили как дубликат, на самом деле не говорит ОП, как решить их конкретную проблему. Он описывает некоторые проблемы, но не является полным решением, поэтому я предоставил ответ, который пытается решить эту конкретную проблему более непосредственно. - person jfriend00; 24.04.2016
comment
Я не минусовал. Я обдумываю, стоит ли мне отозвать свой закрытый голос. - person Oriol; 24.04.2016
comment
@Oriol - изначально я закрыл его как дубликат того же вопроса, но затем передумал, когда понял, что этот другой ответ не полностью говорит ОП, как решить проблему с отправкой формы, которая является конкретным вопросом здесь. Я добавил дополнительную информацию об этом дубликате в моем ответе в качестве фона и в качестве участника фактического решения. - person jfriend00; 24.04.2016
comment
@jfriend00 jfriend00 Наконец-то я нашел решение: else alert('успешно загружено'); document.getElementById('form1').submit(); ////////////////////////////////////////////////// /////////////////////////// ‹form action=paypal.com/cgi-bin/webscr method=post target=_blank id=form1 onsubmit=getMeta(); return false;› ////////////////////////////////// Большое спасибо, вы мне очень помогли - person king bla; 24.04.2016
comment
@kingbla - Поскольку похоже, что вы здесь относительно недавно, если на ваш вопрос уже есть ответ, вы можете сообщить об этом сообществу, щелкнув галочку слева от ответа, который помог вам больше всего. Это также принесет вам несколько очков репутации, которые могут привести к получению дополнительных привилегий на сайте. - person jfriend00; 24.04.2016