LoginSignup
shiki_968
@shiki_968

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

javascriptで、プログレスバーのようなものを追加したい

Q&AClosed

解決したいこと

Javascriptを使って、複数のエクセルファイルを読み込んでいます。
この処理に、プログレスバーのようなもの(「n件読み込みました」と表示)を追加したいです。
どのように書けばよいでしょうか。

※ソースコードは簡略化しています

該当するソースコード


// ブラウザの「実行」ボタンで呼ばれる
// チェックされたファイルを読み込む
function execute(){
    for(i=0; i<cnt; i++){
        path = document.all["path" + i].value
        fetch_excel(path);
        // プログレスバーを追加したい場所
    }
}

function fetch_excel(path){
    //指定したパスのエクセルを開き、データを読み込む
}


自分で試したこと

fetch_excelを呼び出したあとに
「document.all.item("notice").innerHTML = i + "件処理しました"」
と書きましたが、すべての処理が終了しないと画面が更新されませんでした。

0

3Answer

fetch_excel関数の呼び出し後に、updateProgress関数を呼び出して進捗バーと読み込まれたレコード数を更新することができます。

function execute() {
  for (let i = 0; i < cnt; i++) {
    const path = document.all["path" + i].value;
    fetch_excel(path);
    updateProgress(i + 1);
  }
}

function fetch_excel(path) {
  // 指定されたパスのExcelを開き、データを読み込む
}

function updateProgress(processedCount) {
  const totalFiles = cnt;
  const progress = (processedCount / totalFiles) * 100;

  document.getElementById("progress").style.width = progress + "%";
  document.getElementById("notice").innerHTML = "読み込み済みレコード数: " + processedCount;
}

updateProgress関数は処理済みのファイル数をパラメータとして受け取り、進捗のパーセンテージを計算して進捗バーの幅(width)を更新します。また、読み込まれたレコード数をnotice要素に表示します。

2

Comments

  1. @shiki_968

    Questioner

    ありがとうございます。width属性で進捗バーを変化させる方法があるのですね。

ブラウザの設定にもよるかもですが、javascriptでは「あるプロセス内で書き換えた内容は、そのプロセスが完全に終わるまで更新されない」という事が起こります。
その為

fetch_excelを呼び出したあとにdocument.all.item("notice").innerHTML = i + "件処理しました";
と書きましたが、すべての処理が終了しないと画面が更新されませんでした。

という事が発生します。

ではどうすればいいのかと言いますと、各ファイル処理のプロセスを分けてやるとうまく動く……はずです。ですので、一件処理が終わるごとに、「次の処理を行う別プロセス」を動かすようにします。

以下はサンプルコードです。参考になれば幸いです。

<p id="message"></p>
<button onclick="execute()">実行</button>
<script>
  
  let cnt = 10;
  let done = 0;
  function execute(){
    //const path = document.all["path" + done].value;
    const path = "file" + done; // テスト用
    fetch_excel(path);
    done++;

    // メッセージを更新
    // プログレスバーなどについてもここで更新(ここでは割愛)
    document.getElementById("message").innerText =  done + "件処理しました";

    // もし次の処理が控えているなら、もう一度execute関数を「別プロセスとして」実行する
    if(done < cnt){
      // setTimeoutは第一引数の関数を別プロセスとして起動する。
      // なお、第二引数の0はdelay[ms]。ここでは0を指定。
      setTimeout(execute, 0);
    }
  }

  function fetch_excel(path){
    // 時間のかかる処理
    console.log(path);
    for(let i=2;i<1000000;i++){
      let number = i;
      while(number != 1){
        if(number % 2 == 0)number/=2;
        else number=number*3+1;
      }
    }
  }

</script>
2

Comments

  1. @shiki_968

    Questioner

    ありがとうございます。setTimeoutはfor文の中に書くのではなく、処理の終わりに書かないといけないのですね。

前の回答と同様です。 0からcntまでのループなので、iの値が大きくなるにつれてパーセント値が変化します。

そこで、現在のファイル数を表すパラメータを含む関数を定義します。バーと CSS を使用して現在の進行状況を表します、

const progressBar = document.getElementById('progress-bar');

const totalQuestions = 100;

function updateProgressBar(checked) {
  
  const progress = (checked / total) * 100;
  progressBar.style.width = `${progress}%`;
}

したがって、updateProcessBarを呼び出すたびにwidth属性を更新します。

1

Comments

  1. @shiki_968

    Questioner

    ありがとうございます。CSSを使うといいんですね。

Your answer might help someone💌