二重送信防止スクリプト

/web/javascript

Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。

送信ボタンの連打防止スクリプト。ボタンを無効化する方法では、システム側の問題で送信できなくなったりもしたので、大きめの<div>を上に被せてしまうことにしました。

  1. <form action="#" method="post">
  2. <p>
  3. <input type="text" value="" />
  4. <input type="submit" value=" 送信 " />
  5. <input type="image" src="" alt=" 送信 " />
  6. </p>
  7. </form>

実際の動作はサンプルページで確認してもらうとして、この場合のHTMLはこれだけでOKです。

Script

  1. window.onload = createOBJ;
  2.  
  3. function createOBJ() {
  4. if (!document.getElementsByTagName('form')){ return; }
  5.  
  6. // Create object
  7. //
  8. // <div id="wrapper">
  9. // <p>処理中です...<br /><img src="./loading.gif"></p>
  10. // </div>
  11. //
  12. var objBody = document.getElementsByTagName("body")[0];
  13.  
  14. var objWrap = document.createElement("div");
  15. objWrap.setAttribute('id','wrapper');
  16. objWrap.style.display = 'none';
  17. objBody.appendChild(objWrap);
  18.  
  19. var objText = document.createElement("p");
  20. objText.innerHTML = '処理中です...<br />';
  21. objWrap.appendChild(objText);
  22.  
  23. // Set image
  24. var back = new Image();
  25. var objImg = new Image();
  26. back.src = './transparent.png';
  27. objImg.src = './loading.gif';
  28. objText.appendChild(objImg);
  29.  
  30. // Add events
  31. x = document.getElementsByTagName('input');
  32. for(i=0;i<x.length;i++) {
  33. if(x[i].getAttribute('className') == 'cancel' || x[i].getAttribute('class') == 'cancel') continue;
  34. if(x[i].type == 'submit' || x[i].type == 'image') {
  35. x[i].onclick = function(){ veilofDarkness(objWrap, this)};
  36. x[i].onkeypress = function(){ veilofDarkness(objWrap, this)};
  37. }
  38. }
  39. }
  40.  
  41. function veilofDarkness(wrap,obj) {
  42. scroll(0,0);
  43. window.setTimeout( function() { obj.disabled = true;}, 1)
  44. wrap.style.display = 'block';
  45. window.setTimeout( function() { obj.disabled = false;}, 5000)
  46. }

onloadで実行し、要素を生成した上で隠す。同時にonclickイベントを付加し、イベント起動時に要素を展開してフォームを隠す。setTimeout()はIE用。IEはsetTimeout()が無いと連打できちゃいます。

<div>要素に乗っけたロード画像と半透明の背景画像は、削除しても動作上は問題ない。用途に応じてカスタムしてください。世の中には便利なサービスもあるので~。

memo: 送信ボタンに「class="cancel"」を付けたとき、無効になるように調整しました。送信後にリロードしない場合とかに。

CSS

  1. #wrapper {
  2. position: absolute;
  3. top: 0;
  4. left: 0;
  5. width: 100%;
  6. height: 100%;
  7.  
  8. color: #fff;
  9. background: transparent url(transparent.png) repeat !important;
  10. background: none;
  11. filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="./transparent.png", sizingMethod="scale");
  12. text-align: center;
  13. }
  14. #wrapper p {
  15. position: relative;
  16. left: 0;
  17. top: 30%;
  18.  
  19. width: 200px;
  20. margin: 0 auto;
  21. }
  22. #wrapper img {
  23. padding: 10px;
  24. }

生成した<div>要素用のCSS。これに関しては、特に語ることは無いかな。AlphaImageLoaderに関しては、以前のエントリに纏めてあります。

Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。