2017年2月10日金曜日

HTAで「少々お待ちください。。」を表示する

できれば待ち時間を作りたくはないけれども、処理の規模が大きくてどうしても待ち時間が生じてしまう場合は「すみませんが、現在全力で処理中ですので少々お時間ください」的な表示を出したい場合があります。

そのような表示を出すサンプルを作成しました。

ソース
<html>
<head>
<title>最前面</title>
<style type="text/css">
.max{width:100%;height:100%;}
.w-max{width:100%;}
.ta-c{text-align:center;}
button{width:25%;padding:3px;}
</style>
</head>
<body style="overflow:hidden;margin:0px;">
<div id=div最前面 style="display:none;position:absolute;top:0px;left:0px;" class=max>
<div style="position:absolute;background-color:#000;filter:alpha(opacity=50);" class=max></div>
<table class=max style="position:absolute;"><td class=ta-c><table onClick="event.cancelBubble=true"><td id=td最前面 style="background-color:#fff;padding:10px;">少々お待ちください。。</td></table></td></table>
</div>
<table class=max>
<tr height=1>
<td>
<select id=sel class=w-max></select>
<textarea id=ta0 class=w-max style="height:100px;"></textarea>
<button id=btn>now Date</button>
<button id=btn1>最前面1</button>
<button id=btn2>最前面2</button>
<button id=btn3>最前面3</button>
</td>
</tr>
<tr><td><textarea id=ta1 class=max></textarea></td></tr>
</table>
</body>
<script>
resizeTo(350,550)
fun=function(){ var f; eval('f = '+ta0.value); f() }
fun追記=function(elem){ ta1.value += (new Date()) + '\n' + elem.innerText +'\n\n' }
btn.onclick = function(){ fun追記(this) }
btn1.onclick = function(){
fun追記(this)
div最前面.style.display = 'block'
fun()
div最前面.style.display = 'none'
}
btn2.onclick = function(){
fun追記(this)
div最前面.style.display = 'block'
setTimeout(fun2,0)
}
fun2=function(){
fun()
div最前面.style.display = 'none'
}
btn3.onclick = function(){
fun追記(this)
div最前面.style.display = 'block'
setTimeout(fun3,0)
}
fun3=function(){
fun()
setTimeout(function(){div最前面.style.display = 'none'},0)
}
onload=function(){
var ops=sel.options, i=0
ops[i++] = new Option('cmd /C settimeout /T 5', function(){ (new ActiveXObject('WScript.Shell')).Run('cmd /C timeout /T 5', 1, true) })
ops[i++] = new Option('while', function(){ var f=function(){return (new Date()).getTime()}, t=f(); while((f()-t)<5000){} })
ops[0].selected = true
sel.onchange()
}
sel.onchange=function(){ ta0.value = sel.options[sel.selectedIndex].value }
</script>
</html>
view raw please wait.hta hosted with ❤ by GitHub



処理中の画面表示



最上段のエレメントから順番に説明すると

セレクトメニューを切り替えると、待ち時間を必要とする処理の種類を変えられます。

テキストエリア内の中身を書き換えると、処理内容を微調整できます。

4つのボタンはクリックすると最下段のテキストエリアに、押した時刻と押したボタン上の表示文字列を追記します。

3つの「最前面*」のボタンは中身が微妙に違います。
最前面1は1つのfunction内部で「少々お待ちください。。」のstyle.displayをnone→block→noneに切り替えています。

最前面2は2つのfunctionを使い、1つめのfunctionで「少々お待ちください。。」のstyle.displayをnone→blockにして、2つめのfunctionでnoneに切り替えています。

最前面3は3つのfunctionを使い、1つめのfunctionで「少々お待ちください。。」のstyle.displayをnone→blockにして、3つめのfunctionでnoneに切り替えています。


cmd.exeなどの外部プログラムを起動する場合は「最前面1」の方法でも「少々お待ちください」が表示されますが、whileなどのループ処理で待ち時間が生じるようなケースでは「最前面1」の方法では「少々お待ちください」が表示されず、処理中は以下のような見た目になります。


画面の表示内容を変更する処理は、それを行ったfunctionが終了したタイミングで実際に画面上の表示に反映されるようです。

それならば「最前面2」のように、1つめのfunctionでstyle.displayをblockにして、2つめのfunctionで待ち時間が必要な処理をやりつつdisplayをnoneにすれば良いかと思いきや、少々気になる点がありました。
それは…「少々お待ちください」が表示されている最中に、何かのボタンをクリックすると反応してしまうという点です。

セレクトメニューを「while」にして「最前面2」をクリックした直後(少々お待ちくださいが表示されている間)に「now Date」や「最前面1」などをクリックすると、以下のようになります。

「最前面2」を18時31分18秒にクリックして5秒間分の処理がまず予約されて、その5秒間のうちに他のボタンをクリックして「予約された新たな処理」が18時31分18秒の5秒後に開始したということです。

1つのfunctionが処理されている間は画面更新は止まっていますが、クリック操作は受け付けるということのようです。(ただしJavaScriptはシングルスレッドなので受け付けるけど現在実行中のfunctionがあるならその後に予約する、という形になる)

上記を踏まえて「少々お待ちください」が表示されている最中は他の機能を発動できないようにしたい場合は「最前面3」のように、待ち時間が必要な処理が終わってから、別のfunctionでstyle.displayの値を変更すれば良いようです。

0 件のコメント:

コメントを投稿