ホームページ制作 オフィスオバタ

ボタンの二度押しをwait画面でガードしてみた。

以前フォームの二重送信をガードする方法について書いた記事があります。

これは、ブラウザの更新ボタン(F5ボタン)連打をガードする方法です。

ただこの方法でもガードできない事象があります。

それは「送信ボタン連打」です。

画面が切り替わる前に送信ボタンを連打すると、重複起動が発生し誤動作することがあります。
しかもページが重いと余計にボタン連打されやすくなります。

利用される方の身になって考えれば、ボタンを押しても画面が切り替わらなかったら、失敗したのかと思って再度ボタンを押すものです。

今回はこのボタン連打を、どうすればガードできるかについて考え実践しました。
またご参考になれば幸いです。

ひらめいたのは「お待ちください画面表示」でボタンを押せなくする方法

やり方はいろいろ考えられます。
例えばボタンを1回押したらJqueryで無効化して押せなくする、1回押したら非表示にするなどです。

でもこれだと、aタグ(リンクタグ)での対応が難しいです。

そこで思いついたのが、「お待ちください画面」を最前面に表示して強制的にボタンが押せなくする方法です。

表示ページの最前面に、強制的に別の内容で覆いかぶせれば操作ができなくなります。
スマートホンでホームページを見ている際に、メニューボタンを押した後に表示されるメニューボタンのイメージです。(メニューは押せるけれどもともとのリンク等は押せなくなる)

これなら上手くいくのではないかと思い、実践しました。

実際にできたものがこちらです

ボタンの二度押しをガードするサンプル

サンプルは、ボタンを押すと「お待ちください」画面が表示されます。
その間はもともとのボタンが押せなくなります。

切り替わったページ表示時に「お待ちください画面」を出す手法がありますが、今回はページ切り替え前に先に「お待ちください画面」を出すという方法です。

※サンプルは効果がわかりやすいように、2秒間のwait処理が入っています。

ボタンを押したらお待ちくださいを表示する仕組み

今回の仕掛けについて解説いたします。
まずは原理について解説します。

今回の方法は以下の2つの仕掛けがあります

これだけです。

Jqueryには.show()関数があります。
この関数は「非表示状態」のものを「表示状態」にします。

ボタンが押されたタイミングで.show()をコールするだけです。
Jqueryの処理としては、基本的な処理だけでできます。

ソースはこちらです

<!doctype html>
<html>
<head>
<meta charset="shift_jis">
<title>wait切り替え</title>
<style type="text/css">
#wait
{
/** 全画面に強制表示する部分 */
	position: fixed;
	z-index: 999999;
	top: 0px;
	left: 0px;
	width: 100%;
	height: 100%;

/** 最初は非表示にしておく */
	display: none;

/** 全画面の背景色 */
	background-color: rgba(0, 0, 0, 0.8);
	padding-top: 70px;
	text-align: center;
}

#wait .wak
{
	font-size: 24px;
	font-weight: normal;
	line-height: 140%;
	color: #FFF;
	display: inline-block;
	text-align: center;

	padding-top: 20px;
	padding-right: 40px;
	padding-bottom: 20px;
	padding-left: 40px;

	border: 1px solid #999;
	border-radius: 6px;
	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
}

body
{
	text-align: center;
}

a
{
	background: #ffffff; /* Old browsers */
	background: -moz-linear-gradient(top,  #ffffff 0%, #f1f1f1 50%, #e1e1e1 51%, #f6f6f6 100%); /* FF3.6-15 */
	background: -webkit-linear-gradient(top,  #ffffff 0%,#f1f1f1 50%,#e1e1e1 51%,#f6f6f6 100%); /* Chrome10-25,Safari5.1-6 */
	background: linear-gradient(to bottom,  #ffffff 0%,#f1f1f1 50%,#e1e1e1 51%,#f6f6f6 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f6f6f6',GradientType=0 ); /* IE6-9 */
	display: inline-block;
	padding-top: 20px;
	padding-right: 30px;
	padding-bottom: 20px;
	padding-left: 30px;
	border: 1px solid #333;
	color: #333;
	text-decoration: none;
	border-radius: 6px;
	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
}

a:hover
{
	background: #ffffff; /* Old browsers */
	background: -moz-linear-gradient(top,  #ffffff 0%, #f3f3f3 50%, #ededed 51%, #ffffff 100%); /* FF3.6-15 */
	background: -webkit-linear-gradient(top,  #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%); /* Chrome10-25,Safari5.1-6 */
	background: linear-gradient(to bottom,  #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */
}

</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function()
{
	$("a").click(function()
	{
		$("#wait").show();
	});
});
</script>


</head>

<body>
<h1>1ページ目</h1>
<p>下のボタンを押すと2秒後に次の画面へ移動します。</p>
<a href="02.html">次の画面へ移動</a>

<!-- お待ちください画面 -->
<div id="wait">
<div class="wak">
<div class="icon"><img src="default.svg" width="100" height="100"></div>
<p>処理しています<br>少々お待ちください</p>
</div></div>
<!-- お待ちください画面ここまで -->
</body>
</html>

部分的に解説いたします

ソースは全体を見るとよくわかりませんが、部分的にみるとわかりやすくなります。
部分的に解説いたします。

(1)お待ちください画面

お待ちください画面は、CSSだけで作ります。
fixedにすることで、強制的に前面に表示させています。

■HTML部分

<!-- お待ちください画面 -->
<div id="wait">
<div class="wak">
<div class="icon"><img src="default.svg" width="100" height="100"></div>
<p>処理しています<br>少々お待ちください</p>
</div></div>
<!-- お待ちください画面ここまで -->

■CSS部分

#wait
{
/** 全画面に強制表示する部分 */
	position: fixed;
	z-index: 999999;
	top: 0px;
	left: 0px;
	width: 100%;
	height: 100%;

/** 最初は非表示にしておく */
	display: none;

/** 全画面の背景色 */
	background-color: rgba(0, 0, 0, 0.8);
	padding-top: 70px;
	text-align: center;
}

#wait .wak
{
	font-size: 24px;
	font-weight: normal;
	line-height: 140%;
	color: #FFF;
	display: inline-block;
	text-align: center;

	padding-top: 20px;
	padding-right: 40px;
	padding-bottom: 20px;
	padding-left: 40px;

	border: 1px solid #999;
	border-radius: 6px;
	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
}

お待ちください画面で重要なのは以下の7行のcssです。

position: fixed;
z-index: 999999;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
display: none;

これを記述しておけばOKです。
あとは好みの装飾をするだけです。
最初は「非表示」にしておくことも肝要です。

(2)Jquery部分

$(document).ready(function()
{
	$("a").click(function()
	{
		$("#wait").show();
	});
});

aタグがクリックされたら「お待ちください画面」を表示に切り替えています。

この2つの仕掛けでボタン連打をガードできるようになります。
なぜならば、1回押したあとに「お待ちください画面」が最前面に表示されるため、ボタンが強制的に押せなくなるためです。

疑問:_blankリンクをクリックした場合wait画面が表示中のままになりませんか?

今回の方法は、ボタンクリックで強制的に「お待ちください画面」を表示します。
これは、ページが切り替わることが前提のため「お待ちください画面」を消す必要がないからです。

ところが、target=”_blank” (別ウィンドウで表示)にしてしまうと、元画面は「お待ちください画面」表示中のまま固まってしまいます。

_blankを使わなければそれでよいのですが、それでも具合の悪い現象です。
これを何とかする方法はないものでしょうか?

今回、二度押しガード処理を作っていく中で、_blankで「お待ちください画面」で固まる現象についても確認しました。

これに関しても、うまい対処方法があります。
そのやり方については、次回解説いたします。

モバイルバージョンを終了