У меня есть несколько форм на странице, содержащих элементы виджета для загрузки изображений. Может быть одна, а может быть 10. Я пытаюсь динамично, индивидуально уловить именно эти формы on submit. Вот что у меня есть, но на submit оно просто обновляет страницу. Есть идеи, как заставить это работать?
Вот форма:
<form id = "med_blog_form_<?=$b['blog_med_id']?>" name = "med_blog_form" class = "med_blog_form" action = "#" method = "post">
<label for = "media_blog_file_<?=$b['blog_med_id']?>">
<div class = "btn_sm edit_blog_med_btn">UPLOAD</div>
<input type = "file" id = "media_blog_file_<?=$b['blog_med_id']?>" data-blog_med_id = "<?=$b['blog_med_id']?>" class = "media_blog_file" name = "media_upload" hidden/>
<input type = "hidden" name = "upload_type" value = "blog_media_upload" />
<input type = "hidden" name = "blog_id" value = "<?=$blog_id?>" />
<input type = "hidden" name = "filename" value = "<?=$b['src']?>" />
</label>
</form>
и вот jQuery:
$(".media_blog_file").change(function() {
blog_med_id = $(this).data("blog_med_id");
this_form = $(this).closest("form");
this_form.submit();
this_form.on('submit',(function(e) {
e.preventDefault();
alert("form submit "+blog_med_id);
//do other stuff here...
})
)
})
вы звоните submit перед добавлением прослушивателя событий



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Здесь есть пара проблем...
Не регистрируйте обработчики событий внутри обработчиков событий. Это редко/никогда то, чем вы хотите заниматься
Вам действительно не нужен jQuery для этого
Вместо этого добавьте два делегированных обработчика событий; один для прослушивания изменений файла и запуска событий отправки, а другой для прослушивания событий отправки формы
document.addEventListener('change', (e) => {
if (e.target.matches('input[type=file].media_blog_file')) {
e.target.closest('form')?.requestSubmit();
}
});
document.addEventListener('submit', (e) => {
if (e.target.matches('form.med_blog_form')) {
e.preventDefault();
const blog_med_id = e.target.querySelector(
'input[type=file][data-blog_med_id]',
)?.dataset.blog_med_id;
// alert(`form submit ${blog_med_id}`);
console.info('form submit:', blog_med_id);
}
});<!-- note PHP parts have been replaced with static values -->
<form id = "med_blog_form_1" name = "med_blog_form" class = "med_blog_form" action = "#" method = "post">
<label for = "media_blog_file_1">
<div class = "btn_sm edit_blog_med_btn">UPLOAD</div>
<input type = "file" id = "media_blog_file_1" data-blog_med_id = "1" class = "media_blog_file" name = "media_upload" hidden/>
<input type = "hidden" name = "upload_type" value = "blog_media_upload" />
<input type = "hidden" name = "blog_id" value = "1" />
<input type = "hidden" name = "filename" value = "my_file" />
</label>
</form>Я использую метод HTMLFormElement: requestSubmit() вместо просто .submit(), поскольку последний (в ванильном JS) обходит прослушиватели событий и напрямую отправляет форму.
jQuery .submit() (он же .trigger('submit')) ведет себя почти так же, как requestSubmit().
Не волнуйся @Chris. Я бы, наверное, поместил атрибут data в <form>, мне кажется, там это имело бы больше смысла.
Следует быть осторожным: OP .submit() — это jquery $("form").submit(), который отличается от javascript $("form")[0].submit(). Javascript .submit() не будет запускать события отправки jquery submit, а jquery .submit() будет.
Не совсем понятно, что вы пытаетесь сделать. Если я предполагаю, я бы сказал, что вы хотите инициировать событие отправки для формы при изменении значения файла, но вы также обрабатываете это событие отправки в JS. Это звучит правильно?