kmnrk3131
@kmnrk3131 (ひろすけ)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Djangoでview実行中にローディング画面を表示させたい

Djangoでview実行中にローディング画面を表示させたい

Djangoのviewで処理実行の間ローディング画面を表示するにはどうしたらいいですか?

アップしたデータを処理して返すということをしていて、基本的にはローディング画面は必要ないのですが、重いデータをアップした際、時間がかかってしまいます。
そのためviewの処理時間が1.5秒以上経過したらその時点でローディング画面を表示し、処理完了ロード完了したらコンテンツを表示。1.5秒以内で終了するならローディング画面は表示しない。
というようにしたいです。

解決方法を教えて下さい。

試したこと

htmlとcssでローディング画面の作成、jsでクリックしてローディング画面表示はできました。

base.html

<!--ローディング画面-->
<div id="loader">
    <div class="loader_modal">
        <span></span>
        <span></span>
        <span></span>
        <h2>Now loading...</h2>
    </div>
</div>

〜〜〜省略〜〜〜

<!--アップロードフォーム-->
<form method="POST" class="form" enctype="multipart/form-data">
    {% csrf_token %}
    <div class="file-upload-wrapper">
        <p>ファイルを選択<br>
            {{ form.file }}
        </p>
        <p>値を入力<br>
            {{ form.columuns }}
        </p>
        <p>値を入力<br>
            {{ form.code }}
        </p>
    </div>
    <p>ファイルをアップロードし、処理したファイルをダウンロードする</p>
    <button type="submit" class="save btn btn-outline-primary" id="btn">実行</button>
</form>

cssの #loader「hidden」「visible」で表示、非表示を切り替えようとしました。

main.css
/* loading */

@keyframes animation {
    0% {
        transform: rotate3d(1, 1, 0, 360deg);
    }
    50% {
        transform: rotate3d(0.5, 0.5, 0.5, 180deg);
    }
    100% {
        transform: rotate3d(0, 0, 1, 0deg);
    }
}

#loader {
    position: fixed;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.8);
    z-index: 4;
    visibility: hidden;
}

.loader_modal {
    position: relative;
    top: 50%;
    left: 50%;
    width: 250px;
    height: 250px;
    transform: translate(-50%,-50%);
    display: flex;
    align-items: center;
    justify-content: center;
}

.loader_modal span {
    animation: animation 5s infinite;
    position: absolute;
    border: 2px solid white;
    width: 100%;
    height: 100%;
}
.loader_modal span:nth-child(2) {
    animation-delay: 0.3s;
}

.loader_modal h2 {
    color: black;
    font-size: 30px;
}

javascriptでクリックした際に表示する。

script.js

document.getElementById("btn").addEventListener("click", function() {
    console.log('ボタンをクリック');
    const loader = document.querySelector("#loader");
        var req = new XMLHttpRequest();
        console.log('ロード中');
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                loader.style.visibility = "visible";
                console.log('通信開始');
                if (req.status == 200) {
                    console.log('通信完了');
                    loader.style.visibility = "hidden";
                }
            }else{
                loader.style.visibility = "visible";
                console.log('通信中');
            }
            }
});

問題点

クリックには適用されるが、viewでの処理は適応されず、ロード画面が非表示にならない。

0

1Answer

この記事が参考になります。
https://qiita.com/ShinyaKato/items/64b6726c361f5377b0f3

 解説しますと、上のコードでは(req.readyState == 4)の時にローディングを表示していますよね?
ですが、このQiitaの記事には(req.readyState == 4)の時すでに通信が終了していると書いているのです。ということは、(req.readyState == 4)で目に見えないくらいの速さでローディングを表示できているにも関わらず、(req.status == 200)ですぐにローディングを終了してしまっているのです。

書くのであれば、req.readyStateがUNSENTやOPENED、HEADERS_RECEIVEDのどれかの時にローディングを表示し始めて、(req.readyState == 4)の時にローディングを消すという実装が必要だと思います。

1Like

Your answer might help someone💌