フォームの送信が実行された際、送信前に別の処理を挟んでから送信を実行したいということがあったのですが、VanillaJSとjQueryで挙動が異なるということがあったのでメモ。
サンプルコード
動作テスト用に以下のようなフォームを用意します。
<form action="./index.html" method="get"> <input type="text" name="name" id="name"> <button>送信</button> </form>
まずはVanillaJSの場合です。
document.querySelector('form').addEventListener('submit', function(e) { console.log('サブミットイベント開始'); // フォーム送信の停止 e.preventDefault(); // 何らかの処理 setTimeout(function() { console.log('処理完了後'); // フォーム送信の実行 document.querySelector('form').submit(); }, 3000); });
コメントに記載している通りですが、フォーム送信を停止してから別処理(今回はsetTimeoutで3秒停止)を行い、その後JavaScriptからフォームの送信を行っています。
VanillaJSの場合は意図したとおりの動作になりました。
VanillaJSのデモページ
次にjQueryの場合です。
$('form').on('submit', function(e) { console.log('サブミットイベント開始'); // フォーム送信の停止 e.preventDefault(); // 何らかの処理 setTimeout(function() { console.log('処理完了後'); // フォーム送信の実行 $('form').submit(); }, 3000); });
基本的にはVanillaJSの記述をjQueryに置き換えただけで実装の流れは変わらないのですが、jQueryの場合はJavaScriptでフォーム送信を行った際にもイベントが発火してしまい、処理がループしてフォームの送信ができませんでした。
jQueryでうまくいかなかった場合のデモページ
対応方法としては、別処理完了後のフォーム再送信の前にsubmitイベントを破棄して、イベントが再発火するとよさそうです。
$('form').on('submit', function(e) { console.log('サブミットイベント開始'); // フォーム送信の停止 e.preventDefault(); // 何らかの処理 setTimeout(function() { console.log('処理完了後'); // フォーム送信時のイベントを破棄 $('form').off('submit'); // フォーム送信の実行 $('form').submit(); }, 3000); });
これで意図した動作にできました。
jQueryで対応後のデモページ
コメントが承認されるまで時間がかかります。