onclickで送信ボタンをdisabledするとonsubmitが発動しない

今回は超小ネタ。送信が完了したなりなんなりかで画面遷移がスムーズに行われないとユーザが訝しんで送信ボタンを何度もクリックして多重送信になる and 管理者や運営者はそれに苦慮する結果、多重送信されないようにして欲しいというニーズは少なからずあると思います。

が、送信ボタンにid=”submit”が割当てられていたとして、JavaScript(jQuery)で単純に

$(function () {
     $("#submit").click(function () {
          $(this).attr("disabled", "disabled");
     });
});

としてもクリックした直後に送信ボタンがdisabledになって一部ブラウザを除いてformの内容を送信できなくなります(WinXP + IE, firefox, GoogleChrome, Opera, Safariで確認してfirefoxのみ送信可)。パッと見、送信ボタンがクリックされたんだからformの内容が送信されて、んでdisabledになる……と見えますが例えば、

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>click test</title>
<script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript">
jQuery(function () {
    jQuery('#submit').live('mousedown', function () {
        console.log('mousedown');
    });
    jQuery('#submit').live('click', function () {
        console.log('click');
        jQuery(this).attr('disabled', 'disabled');
    });
    jQuery('#submit').live('mouseup', function () {
        console.log('mouseup');
    });
    jQuery('#form').live('submit', function () {
        console.log('submit');
        return false;
    });

    jQuery('#retry').live('click', function () {
        var dt = new Date();
        jQuery(this).attr('href', '?' + dt.getTime());
    });
});
</script>
</head>
<body>
<h1>クリックでのイベント発現確認</h1>
<form action="#" id="form" method="get">
<input type="submit" id="submit" value="送信する" />
</form>
<ul>
    <li><a id="retry" href="?">やり直す</a></li>
</ul>
</body>
</html>

というHTMLで送信ボタンをクリックしてconsole.log()の出力を追ってみるとfirefoxを除いて、onclickイベント発動時に送信ボタンをdisabledに変更すると続くonsubmitイベントが発動しないことが分かります。送信ボタンをdisabledすることで多重送信防止を試みる場合は、送信ボタンのonclick時ではなくフォームのonsubmit時が無難ですね。

あと蛇足で、HTMLのサンプルでは今回の確認で特に必要ないmousedownとmouseupでもconsole.logで出力してますが、今回の確認と合わせてクリック回りでイベントの発生順を確認したかったという理由からで、予想通り

  1. mousedown
  2. mouseup
  3. onclick
  4. onsubmit

の順でイベントが発動するわけですが、

  • 送信ボタン上でマウスの左ボタンを押したままカーソルを送信ボタンから外れるとmousedownだけが発動
  • 逆に送信ボタンの外でマウスの左ボタンを押したままカーソルを送信ボタンへ移動し、左ボタンを離すとmouseupのみが発動
  • mousedownとmouseupが揃ってonclickになる

ってのを再確認したのでした。