質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

ボタンを押したときに1~2秒ほどローディング画像が表示されるようにしたいのですが、、、

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,291

score 16

下のプログラムで「結果を表示する」のボタンを押したときに1~2秒ほどローディング画像の表示&フェードアウトするようにしたいのですが、ボタンを押す前からローディング画像が表示されてしまうなど、なかなかうまくいきません。

このプログラムのジャバスクリプトにどうやって記述すればできるようになるのか、教えていただけますでしょうか。

色々調べて、とりあえず下記リンクのサイトなどのやり方を参考に、あれこれやっているのですがローディング画像が思うように表示されないのです。。。

/////////////////////////////////////////////////
参考にしたサイト(2つ)

http://blue-bear.jp/kb/javascript-%E5%87%A6%E7%90%86%E4%B8%AD%E3%81%AB%E3%83%AD%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E7%94%BB%E9%9D%A2%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%97%E3%81%A6%E3%80%81%E5%87%A6/?fbclid=IwAR3iay0oWIptezzx3XWdbEPmCq2Uj02k9RNLiLRLVm-aTos1gZJsbgtDshs

https://haniwaman.com/loading/?fbclid=IwAR0g5WSlyiEEb-fHzPBHdfqbpcrMUebDUrgKtvZycf6oL1ljkT85zD07hiQ

/////////////////////////////////////////////////

ローディング画像はCSSでつくったので、あとはボタンを押せば、ローディング画像が表示されるように、ジャバスクリプトを記述すれば良いだけだと思うのですが、どういった記述をすれば良いかが分かりません。

<script type="text/javascript">
// ◆◆◆ファンクション名◆◆◆
function keisan() {

//////////////////////////////////

この部分にどういったスクリプトを記述すれば良いかが分からない

//////////////////////////////////

// ◆◆◆入力された(anser)の定義◆◆◆
var anser1 = (document.querySelector('#anser1').value);
var anser2 = (document.querySelector('#anser2').value);
// ◆◆◆関数設定◆◆◆
var word1 = 'あいうえお'; 
var word2 = 'ABCDEF'; 
// ◆◆◆テーブル設定◆◆◆
var table1 =<table style="width:300px;"><tbody><tr><td>;
var table2 =</td></tr><tr><th>;
var table3 =</th></tr></tbody></table>;
// ◆◆◆結果の表示◆◆◆
document.querySelector('#anserall').innerHTML = table1+word1+anser1+table2+word2+anser2+table3;
}
</script>

// html部分

<form>
<input id="anser1" type="number" placeholder="0">
<br>
<input id="anser2" type="number" placeholder="0">
<br>
<input type="button" value="結果を表示する" onclick="keisan();">
<br>
<div id="anserall" style="white-space:pre;"></div>
</form>


//ジャバスクリプト

<script type="text/javascript">
// ◆◆◆ファンクション名◆◆◆
function keisan() {
// ◆◆◆入力された(anser)の定義◆◆◆
var anser1 = (document.querySelector('#anser1').value);
var anser2 = (document.querySelector('#anser2').value);
// ◆◆◆関数設定◆◆◆
var word1 = 'あいうえお'; 
var word2 = 'ABCDEF'; 
// ◆◆◆テーブル設定◆◆◆
var table1 =`<table style="width:300px;"><tbody><tr><td>`;
var table2 =`</td></tr><tr><th>`;
var table3 =`</th></tr></tbody></table>`;
// ◆◆◆結果の表示◆◆◆
document.querySelector('#anserall').innerHTML = table1+word1+anser1+table2+word2+anser2+table3;
}
</script>

=========
  
// CSS ローディング画像

 #loading {
 display: table;
 width: 100%;
 height: 100%;
 position: fixed;
 top: 0;
 left: 0;
 background-color: #fff;
 opacity: 0.8;
}

#loading .loadingMsg {
 display: table-cell;
 text-align: center;
 vertical-align: middle;
 padding-top: 140px;
 background: url("img/loading.gif") center center no-repeat;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/03/26 14:01

    WordPressだと色んな前提が崩れます。
    もしかしたらWordPress向けの回答の方が良いかもしれません。
    念のため「WordPress」をタグに追加しておいてください。

    キャンセル

  • m.ts10806

    2019/03/26 14:02

    ※ただ、私はWordPress環境がないので、WordPressというのは関係のない回答をしようと思っています。

    キャンセル

  • TreesShimi

    2019/03/26 14:06

    承知しました。ちなみにWPはこのプログラムを試す際に使っただけなので、たぶん大丈夫です。ありがとうございます。

    キャンセル

回答 1

checkベストアンサー

+3

「コードブロックはファイル毎にわけてもらえたらと。」というのはコードを以下のように分けて欲しかったためのコメントです

※インデント勝手につけました。可読性は大事です
「言語名 整形」とかで出てくるサービスを利用するか、できれば整形機能があるエディタを使ってください

<form>
  <input id="anser1" type="number" placeholder="0">
  <br>
  <input id="anser2" type="number" placeholder="0">
  <br>
  <input type="button" value="結果を表示する" onclick="keisan();">
  <br>
  <div id="anserall" style="white-space:pre;"></div>
</form>
// ◆◆◆ファンクション名◆◆◆
function keisan() {
    // ◆◆◆入力された(anser)の定義◆◆◆
    var anser1 = (document.querySelector('#anser1').value);
    var anser2 = (document.querySelector('#anser2').value);
    // ◆◆◆関数設定◆◆◆
    var word1 = 'あいうえお';
    var word2 = 'ABCDEF';
    // ◆◆◆テーブル設定◆◆◆
    var table1 = `<table style="width:300px;"><tbody><tr><td>`;
    var table2 = `</td></tr><tr><th>`;
    var table3 = `</th></tr></tbody></table>`;
    // ◆◆◆結果の表示◆◆◆
    document.querySelector('#anserall').innerHTML = table1 + word1 + anser1 +
        table2 + word2 + anser2 + table3;
}
#loading {
 display: table;
 width: 100%;
 height: 100%;
 position: fixed;
 top: 0;
 left: 0;
 background-color: #fff;
 opacity: 0.8;
}

#loading .loadingMsg {
 display: table-cell;
 text-align: center;
 vertical-align: middle;
 padding-top: 140px;
 background: url("img/loading.gif") center center no-repeat;
}

本題

まずはHTML上にローディングをHTMLとして置いてあげます。
CSS的にfixedなのでおおよそどこに置いても同じはずなので、とりあえず冒頭に

<div id="loading">
    <div class="loadingMsg"></div>
</div>
<form>
  <input id="anser1" type="number" placeholder="0">
  <br>
  <input id="anser2" type="number" placeholder="0">
  <br>
  <input type="button" value="結果を表示する" onclick="keisan();">
  <br>
  <div id="anserall" style="white-space:pre;"></div>
</form>


※loading.gifはネットから適当に拾ってきました。
イメージ説明

「クリックしたときに」が条件なので、非表示にします。

<div id="loading" style="display:none;">
    <div class="loadingMsg"></div>
</div>
<form>
  <input id="anser1" type="number" placeholder="0">
  <br>
  <input id="anser2" type="number" placeholder="0">
  <br>
  <input type="button" value="結果を表示する" onclick="keisan();">
  <br>
  <div id="anserall" style="white-space:pre;"></div>
</form>


イメージ説明

「1~2秒ほど表示する」とのことなので、プログラム的にはクリック時に表示して指定した時間が経過したら非表示にすると言う風になります。

とりあえず表示させます。

function keisan() {
    // ◆◆◆入力された(anser)の定義◆◆◆
    var anser1 = (document.querySelector('#anser1').value);
    var anser2 = (document.querySelector('#anser2').value);

    var loader = document.getElementById('loading');
    loader.style.display = '';//blockではなく、空にする(でないとdisplay:table;を上書きしてしまうので元の表示ではなくなる)
//後略
//

「任意の時間経過後に処理を~~」というのはsetTimeOut()という関数が有用です。

function keisan() {
    // ◆◆◆入力された(anser)の定義◆◆◆
    var anser1 = (document.querySelector('#anser1').value);
    var anser2 = (document.querySelector('#anser2').value);

    var loader = document.getElementById('loading');
    loader.style.display = '';
    setTimeout(endLoader,2000);

//中略

function endLoader(){
    var loader = document.getElementById('loading');
    loader.style.display = 'none';
}

クリック前
イメージ説明

クリック時
イメージ説明

2秒経過後
イメージ説明

蛇足

今回は質問者さんのコードに乗せる形で作りはしたのですが、
要件をもう少し細かく詰めてもらえればもっと適切な組み方があるように思います。
WordPressとのことで確かデフォルトでjQuery読み込むようになってたはずなので、
jQuery利用したほうが簡潔に組めるといえば組めますし、アニメーションも楽にできます。
※PureJavaScriptの方が動作が速く、jQueryから離れる動きもありますが、私はこちらの方が書きやすいのでまだまだ使っていっています。

  <input type="button" value="結果を表示する" id="result">
    #result_table{
        width:300px;
    }
$(function(){
    $('#anserall').hide();
    $("#result").on('click',function(){
        $("#loading").fadeIn();
        setTimeout(endLoader,2000);
        const anser1 = $('#anser1').val();
        const anser2 = $('#anser2').val();

        const word1 = 'あいうえお';
        const word2 = 'ABCDEF';

        let result_table = $('<table></table>',{
            'id':'result_table'
        });

        let tbody = $('<tbody></tbody>');
        let td = $('<tr><td></td></tr>');
        td.text(word1 + anser1);
        let th = $('<tr><th></th></tr>');
        th.text(word2 + anser2);
        tbody.append(td);
        tbody.append(th);

        result_table.append(tbody);        
        $("#anserall").append(result_table);

    });
});

const endLoader = function(){
    $("#loading").fadeOut();
    $('#anserall').show();
};

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/26 18:23

    と思ったけど、改めるようですね。了解です。
    かなり長いコードのようですが、別ファイルで最低限の内容で「ミニマムコード」を作って試して調整すると良いです。最低限の内容でできないことはできませんので。
    あと最低限のコードで試すとどこに問題があるか見えてくることもあります。

    新しく質問するときは「どこまで動作しているか」「確認した端末、ブラウザ」もつけると良いです。
    環境依存がないとは限らないので。

    キャンセル

  • 2019/03/27 09:31

    おはようございます!
    アドバイスいただいたようにミニマムコードで試作したところ、スマホでも問題なく動作しました!
    ただ、本チャンのコードで試すと動作しなくなるので、そちらのコードに問題があるようです。
    それを探し出せれば解決できそうなので、今日はとりあえず自力で頑張ります。
    mts10806さん、ありがとうございました!

    キャンセル

  • 2019/03/27 09:34

    たぶん他のコードとかCSSとかが壁になっていることはよくあります。
    少しずつもとのコードに戻していって原因となっている箇所を突き止めるところからですね。
    がんばってください。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る