時間がかかる処理をする時に、画面に変化がないと不安になります。
ということで、ローディング画面を作ってみます。
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<title>loading scene</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src='loading.js'></script>
</head>
<body>
<div class="wrap">
<div id="_loading">
<div id="_loadingText">now loading...</div>
</div>
<button type="button" id="loadingButton" name="button">読み込みボタン</button>
</div>
</body>
</html>
html {
font-size: 16px;
}
.wrap {
margin: auto;
padding-top: 3rem;
width: 99%;
height: 100vh;
background-color: #eeeeee;
text-align: center;
}
button {
margin: 1rem;
min-width: 100px;
color: #fff;
background-color: #eb6100;
border-bottom: 5px solid #b84c00;
-webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
}
button:hover {
/* margin-top: 3px; */
color: #fff;
background: #f56500;
border-bottom: 2px solid #b84c00;
}
#_loading {
display: none;
background-color: #eeeeeecc;
position: fixed;
width: 100%;
height: 100vh;
top: 0;
left: 0;
}
#_loadingText {
padding-top: 30%;
font-size: 3rem;
}
window.onload = () => {
// ローディング要素外枠の id と外枠
const loadingOuterId = '_loading';
const loadingOuter = document.getElementById(loadingOuterId);
// ローディング中の描画テキスト描画用の要素 id とテキスト描画用要素
const loadingTextId = '_loadingText';
const loadingText = document.getElementById(loadingTextId);
// ローディング中に描画するテキスト
const LOADING_TEXT = 'now loading ...';
// ローディング画面描画用のボタン
const loadingButtonId = 'loadingButton';
const loadingButton = document.getElementById(loadingButtonId);
// インターバルタイマーの id
let id = null;
// ボタンがクリックされたらローディング画面を描画する
loadingButton.addEventListener('click', () => {
drawLoading();
});
// ローディング画面の描画関数
const drawLoading = () => {
// すでにタイマーを起動している場合は抜ける
if(id !== null) return;
loadingOuter.style.display = 'block';
loadingText.innerHTML = '';
// 100ms(0.1s)毎に呼び出す
id = setInterval(() => {
// ローディング中に描画するテキストを全て描画し終わったら、ローディング画面を非表示にする
if(LOADING_TEXT.length === loadingText.innerHTML.length) {
// インターバルタイマーをクリア
clearInterval(id);
// ローディング画面を非表示
loadingOuter.style.display = 'none';
id = null;
}
// ローディング中のテキスト
loadingText.innerHTML = LOADING_TEXT.substring(0, loadingText.innerHTML.length + 1);
}, 100);
}
}
document.getElementById
HTML と JavaScript を連携するあれです。
こちらの記事にちょっと詳細が載ってます。
setInterval
今回の主役です。
一定の遅延間隔で処理を繰り返します。
for 文の遅延バージョンみたいなものです。
ただし、非同期です。
id = setInterval(function() {
// time 時間毎に実行したい処理
}, time);
// time の単位は ms(1/1000) です。
1ms = 1/1000s というのは、1000ミリ秒で1秒ということになります。
loading.js 内では、100ms(0.1秒)毎に関数を呼び出しています。
また、setInterval は インターバル ID を返します。
この ID は、一意に決まっており、
clearInterval(id)
とすることで、繰り返し処理を終了できます。
setInterval をむやみやたらに使用すると、動作が重たくなります。
使用しなくなったら、clearInterval しましょう。
ローディング画面を作ってみる
使い方としては、
ローディング画面描画→時間のかかる処理→ローディング画面の非表示
となるはずです。
ということで、
const _loadingOuter = document.createElement('div');
const _outerStyle = 'display:block;background-color:#eeeeeeaa;position:fixed;width:100%;height:100vh;top:0;left:0;';
_loadingOuter.style = _outerStyle;
const _loadingText = document.createElement('div');
const _textStyle = 'padding-top:20%;font-size:3rem;text-align:center;';
_loadingText.style = _textStyle;
_loadingOuter.appendChild(_loadingText);
const _text = 'now loading ...';
let _loadingId = null;
// 読み込み画面を表示する
function drawLoading() {
if(_loadingId !== null) return;
document.body.appendChild(_loadingOuter);
_loadingText.innerHTML = '';
_loadingId = setInterval(() => {
if(_text.length === _loadingText.innerHTML.length) _loadingText.innerHTML = '';
_loadingText.innerHTML = _text.substring(0, _loadingText.innerHTML.length + 1);
}, 200);
}
// 読み込み画面非表示にする
function hideLoading() {
clearInterval(_loadingId);
_loadingOuter.remove();
_loadingId = null;
}
作ってみました。
コピペして読み込むとローディング画面が表示されます。
いろいろ終わって、ローディング画面を非表示にするときは、hideLoading() を呼び出してください。
Loading.js を読み込む場所は </body> タグの下にしてください。
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
<meta charset="utf-8">
<title>counter</title>
<!-- ページのデザインを外部ファイルにまとめるときは CSS を使うと良き -->
<link rel="stylesheet" href="../style.css">
<!-- JavaScript の読み込み (HTML ファイルと JS ファイルは同じディレクトリ階層) -->
<script type="text/javascript" src="counter.js"></script>
</head>
<body>
<div class="wrap">
<p>カウント:<span id="drawCount">0</span></p>
<button type="button" id="countUpButton" name="button">+1</button>
<button type="button" id="countDownButton" name="button">-1</button>
</div>
</body>
<!-- ここで読み込む -->
<script type="text/javascript" src="Loading.js"></script>
</html>
使用してみると、こんな感じになります。