miau's blog?

ダブルクリックの抑止

ちょっと前の話。
今やってる案件で、「Web フォームで submit ボタンをダブルクリックしても、2 回 submit されないようにしてください」との要望(実際には不具合呼ばわりされた)がありまして。
先日読んだCSSクックブックにもそういうレシピ「5.5 1回限り有効な送信ボタンの設定」があったけど、これは onSubmit 時にボタンに display: none なスタイルを適用する強引な方法。これだとキャンセルボタンとか押されたときにどうしようもなくなるでしょ・・・。

もっとまともな方法がありそうなのでググってみると、やっぱりありました。

onsubmit で disable にするやつ

へー。共通の .js に入れるだけで自動的に使えるようになるわけか。
ということで、お客さんに「1 時間くらいで対応できると思いますよ」と伝えたんだけど、これがまずかった。実際組み込んでみるとちゃんと動作しない。

原因は 2 点。
・<body> で onLoad イベントを指定していた。<script>→<body> の順で記述してたから、イベントが上書きされちゃったみたい。
・submit 動作を行うのが <input type="image"> なボタンだったんだけど、type="image" な要素は form.elements として取得できない。

前者の問題は、とりあえず <body> の onLoad イベントにも DisableSubmit.set(); を追記することで対応。
後者の問題は、this.elements の代わりに document.getElementsByTagName('input') を渡すことで対応、と。

ちなみに、setTimeout(〜, 1) を使っているので通常のダブルクリックには対応できるけど、「クリックと同時に Enter」みたいな意地悪をすると二回 submit されるみたい。まあ、

naoyaのはてなダイアリー - submit ボタン disable 技の罠

の対策だろうし、目的は「ついうっかりダブルクリック」を防ぐことだからこれで十分か。
あと、setTimeout(〜, 1000) だと 1 秒後に復活しちゃうけど onStop で実装したほうがしっかり作れるんじゃ?とか思って調べてみたら onStop って IE 特有のイベントみたいで納得。


(追記)

そういえばもう一点変更してたんでした。

if ((elm.type == 'submit' || elm.type == 'image') && !elm.disabled) {
...
}

・・・でしたっけ?なんかすでに変更していただいているような。
とりあえずこれだと引っかからないものが出てくるので、

if (elm.type.match(/^(submit|image|file|button)$/i)) {
if (!elm.disabled) {
...
}
}

こんな感じに。
正規表現で条件判定するのは Perl 厨の悪い癖かもしれないけど、こっちのほうが楽に拡張できるから好きだったり。

posted at 10:08:05 on 2006-07-08 by miau - Category: Work No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

takayama wrote:

こんにちは、スクリプト利用して頂いてありがとうございます。
ですが問題が発生してしまってお時間取らせてしまった事、申し訳なく思います。
今回発生した内容を元にしてスクリプトの改善を行なおうと思っています。
では。
2006-07-08 10:44:45

miau wrote:

>ですが問題が発生してしまってお時間取らせてしまった事、申し訳なく思います。

え。そんなとんでもないです。
すごく助かりました。

そういえばもう一点変更加えたところがあったので、追記してみます。
2006-07-08 12:14:00

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。