JS

ネイティブネタ帳

UI

モーダル

タブ

ドロワー

スライダー

スクロール

アコーディオン

目次

ローディングアニメーション

ツールチップ

ヘッダー

テーブル

グラフ

背景

ニュースティッカー

フォーム

フォーム

文字

文字の装飾

文字の操作

文字のカウント

数字の操作

ウィンドウ

ウィンドウ操作

タイトルの操作

ページ遷移時の動き

class

classの操作

要素

要素の操作

要素の追加

API

WP REST API

Google Books APIs

楽天市場API

openBD

画像・動画

画像の操作

YouTube

リンク

Google Analytics

cookie

検索

検索

お気に入り登録

JavaScriptのfor (let i =)で10問の質問の回答でスコアを出してリダイレクト

お気に入り登録をすると、お気に入り記事一覧に登録することができます。

JavaScriptのfor (let i =)で10問の質問の回答でスコアを出してリダイレクト

JavaScriptのfor (let i =)で10問の質問の回答でスコアを出してリダイレクト

この記事では、JavaScriptのfor (let i =) のループを使って、10問の質問の回答でスコアを出してリダイレクトをかける方法について解説しています。

比較的診断系のコンテンツで使えそうなスニペットなので、参考にしてみてください。

for (let i =)

JavaScriptのforループは、コードブロックを繰り返し実行します。

基本的な形はfor (初期化; 条件; ステップ) {...}です。

  • 初期化: この部分で、ループが始まる前に一度だけ実行される式を書きます。よく使われるのはカウンタ変数の初期化です。
  • 条件: この式がtrueを返す限り、ループは繰り返されます。falseを返すと、ループは終了します。
  • ステップ: この部分のコードは、ループ内のコードブロックが実行された後に毎回実行されます。

例えば、以下の通りです。

let numbers = [1, 2, 3, 4, 5];

for (let idx = 0; idx < numbers.length; idx++) {
  console.log(numbers[idx]);
}

このコードでは、idxというカウンタ変数を使用しています。idxは、index(インデックス)の略で、配列の位置を指すための番号としてよく使われる名前です。

idxの初期値は0(最初の要素の位置)とし、idxが配列の長さ未満である間、console.logを使用して配列の要素を順番に表示します。そして、毎回のループの終わりでidxを1増やしています。

かかかず
かかかず

ループを覚えると、色々できるようになるのでおさえておきましょう。

スコアを出してリダイレクトをするサンプル

早速、サンプルです。

表示される10個の質問に回答していくと、最終的に合計得点が表示されます。合計得点表示後2秒経つと、取得した合計得点に応じて、2秒後にリダイレクトがかかりページ遷移します。

Question 1: YES or NO?

Question 2: YES or NO?

Question 3: YES or NO?

Question 4: YES or NO?

Question 5: YES or NO?

Question 6: YES or NO?

Question 7: YES or NO?

Question 8: YES or NO?

Question 9: YES or NO?

Question 10: YES or NO?

かかかず
かかかず

リダイレクトのページは用意していないので「404」が表示されます。

後述するJavaScriptのコードで「得点の配点」と「リダイレクト」の2つはそれぞれ設定可能です。

実装の手順と方法

手順と方法

コードの詳細の前に、実装の手順と方法について解説していきます。

HTMLを記述

まずは、HTMLを記述します。

設置したい場所に記述しましょう。

<div class="quiz__container">
    <div class="question" data-value="10">
        <p class="question__title">Question 1: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="9">
        <p class="question__title">Question 2: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="8">
        <p class="question__title">Question 3: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 4: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 5: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 6: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 7: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 8: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 9: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="1">
        <p class="question__title">Question 10: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
</div>

<div class="result__container" style="display: none;">
    Your score is: <span id="score">0</span>/100
</div>
JavaScriptを記述

次に、JavaScriptのコードを記述します。

コードは <body>〜</body>で、</body> の閉じタグ(クロージングタグ)の前に記述しましょう。

    // 現在の質問のインデックスを管理する変数
    let currentQuestion = 0;
    
    // 合計得点を管理する変数
    let totalScore = 0;

    // 全質問要素を取得
    const questions = document.querySelectorAll('.question');
    
    // 結果表示部分の要素を取得
    const resultContainer = document.querySelector('.result__container');
    
    // スコア表示部分の要素を取得
    const scoreElem = document.getElementById('score');

    // ボタンがクリックされた時の処理を行う関数
    function nextQuestion(clickedButton, isYes) {
        // クリックされたボタンにactiveクラスを追加
        clickedButton.classList.add('active');

        // YESが選択された場合、得点を加算
        if (isYes) {
            const scoreForThisQuestion = parseInt(questions[currentQuestion].getAttribute('data-value'), 10);
            totalScore += scoreForThisQuestion;
        }

        // 1秒待機後に次の処理へ進む
        setTimeout(function() {
            // activeクラスをクリックされたボタンから削除
            clickedButton.classList.remove('active');
            
            // 現在の質問を非表示にする
            questions[currentQuestion].style.display = 'none';

            // 質問のインデックスを進める
            currentQuestion++;

            // 次の質問を表示するか、結果を表示するか判断
            if (currentQuestion < questions.length) {
                questions[currentQuestion].style.display = 'block';
            } else {
                scoreElem.textContent = totalScore;
                resultContainer.style.display = 'block';

                // 得点に応じて異なるページへリダイレクトする
                setTimeout(function() {
                    if (totalScore <= 20) {
                        window.location.href = 'URL_for_0-20';
                    } else if (totalScore <= 40) {
                        window.location.href = 'URL_for_21-40';
                    } else if (totalScore <= 60) {
                        window.location.href = 'URL_for_41-60';
                    } else if (totalScore <= 80) {
                        window.location.href = 'URL_for_61-80';
                    } else if (totalScore < 100) {
                        window.location.href = 'URL_for_81-99';
                    } else {
                        window.location.href = 'URL_for_100';
                    }
                }, 2000); // 結果表示後、2秒でリダイレクト
            }
        }, 1000); // 1秒後に次の処理を行う
    }

    // 起動時に2番目以降の質問を非表示に設定
    for (let i = 1; i < questions.length; i++) {
        questions[i].style.display = 'none';
    }
CSSを記述

最後にCSSを書いて、見た目を整えましょう。

button:active, .question__btn button.active {
    background: #707070;
    color: #fff;
}

.question {
    display: block;
    animation: fadeIn 0.8s ease 0s 1 normal;
}
.question__btn button {
    display: inline-flex;
    margin: 0;
}
.question__btn {
    display: flex;
    justify-content: center;
    gap: 40px;
}
p.question__title {
    display: block;
    width: 100%;
    text-align: center;
    position: relative;
}

ざっくりとしたコードの解説

コードは、HTML・JavaScript・CSSの3種類です。ざっくりですが、順に解説していきます。

HTML

HTMLのコードは、診断の質問や、ボタンなどインターフェイス部分を表現しています。

<div class="quiz__container">
    <div class="question" data-value="10">
        <p class="question__title">Question 1: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="9">
        <p class="question__title">Question 2: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="8">
        <p class="question__title">Question 3: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 4: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 5: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 6: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 7: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 8: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="10">
        <p class="question__title">Question 9: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
    <div class="question" data-value="1">
        <p class="question__title">Question 10: YES or NO?</p>
        <div class="question__btn">
          <button onclick="nextQuestion(this, true)">YES</button>
          <button onclick="nextQuestion(this, false)">NO</button>
        </div>
    </div>
</div>

<div class="result__container" style="display: none;">
    Your score is: <span id="score">0</span>/100
</div>

コードが多いので、箇条書きで解説すると以下の通りです。

  • コンテナ: <div class="quiz__container"> はクイズ全体のラッピング要素です。この中に各質問が配置されています。
  • 各質問: <div class="question" data-value="10"> は、個々の質問を示しています。data-value 属性はその質問に対するスコアの値を保持しています。例えば、第一の質問の正解は10点の価値があります。
  • 質問のタイトル: 各質問の上部には、<p class="question__title"> を使用して、質問文が表示されます。
  • 回答ボタン: 各質問にはYESとNOの2つのボタンがあります。ユーザーがクリックすると、nextQuestion 関数が呼び出され、クリックしたボタンとその回答が渡されます。
  • 結果の表示: 最後に、<div class="result__container"> があります。初めは style="display: none;" で非表示に設定されていますが、クイズが終了すると表示されるようになっています。この中にはユーザーの合計スコアが<span id="score"> 要素内に表示されます。

このコードを使用して、ユーザーは質問に回答し、最終的にそのスコアを確認。そして、対応したページにリダイレクトが行われます。

かかかず
かかかず

質問の「Question」の文章は、HTMLで制御します。

JavaScript

JavaScriptのコードで、主に「得点の計算方法」「リダイレクト先の指定」「表示の時間差指定」の3つを設定します。

    // 現在の質問のインデックスを管理する変数
    let currentQuestion = 0;
    
    // 合計得点を管理する変数
    let totalScore = 0;

    // 全質問要素を取得
    const questions = document.querySelectorAll('.question');
    
    // 結果表示部分の要素を取得
    const resultContainer = document.querySelector('.result__container');
    
    // スコア表示部分の要素を取得
    const scoreElem = document.getElementById('score');

    // ボタンがクリックされた時の処理を行う関数
    function nextQuestion(clickedButton, isYes) {
        // クリックされたボタンにactiveクラスを追加
        clickedButton.classList.add('active');

        // YESが選択された場合、得点を加算
        if (isYes) {
            const scoreForThisQuestion = parseInt(questions[currentQuestion].getAttribute('data-value'), 10);
            totalScore += scoreForThisQuestion;
        }

        // 1秒待機後に次の処理へ進む
        setTimeout(function() {
            // activeクラスをクリックされたボタンから削除
            clickedButton.classList.remove('active');
            
            // 現在の質問を非表示にする
            questions[currentQuestion].style.display = 'none';

            // 質問のインデックスを進める
            currentQuestion++;

            // 次の質問を表示するか、結果を表示するか判断
            if (currentQuestion < questions.length) {
                questions[currentQuestion].style.display = 'block';
            } else {
                scoreElem.textContent = totalScore;
                resultContainer.style.display = 'block';

                // 得点に応じて異なるページへリダイレクトする
                setTimeout(function() {
                    if (totalScore <= 20) {
                        window.location.href = 'URL_for_0-20';
                    } else if (totalScore <= 40) {
                        window.location.href = 'URL_for_21-40';
                    } else if (totalScore <= 60) {
                        window.location.href = 'URL_for_41-60';
                    } else if (totalScore <= 80) {
                        window.location.href = 'URL_for_61-80';
                    } else if (totalScore < 100) {
                        window.location.href = 'URL_for_81-99';
                    } else {
                        window.location.href = 'URL_for_100';
                    }
                }, 2000); // 結果表示後、2秒でリダイレクト
            }
        }, 1000); // 1秒後に次の処理を行う
    }

    // 起動時に2番目以降の質問を非表示に設定
    for (let i = 1; i < questions.length; i++) {
        questions[i].style.display = 'none';
    }
  • 変数の初期化: currentQuestion は現在の質問のインデックスを管理し、totalScore はユーザーの合計得点を保存します。
  • DOM要素の取得: questions には全質問要素が格納され、resultContainer と scoreElem には結果とスコアの表示部分が格納されます。
  • ボタンクリック時の処理: nextQuestion 関数は、ユーザーが回答ボタンをクリックした際に呼び出されます。この関数は、得点の計算、現在の質問の非表示、次の質問の表示、または結果の表示といった一連の処理を行います。
  • 得点の判断: ユーザーが全ての質問に答えた後、その得点に基づいて異なるページへリダイレクトします。このリダイレクト処理は、結果の表示から2秒後に実行されます。
  • 初期設定: アプリの起動時に、2番目以降の質問を非表示にするループがあります。これにより、最初に1つ目の質問のみが表示され、残りの質問は非表示に設定されます。

このコードで、質問に回答し、最終的にそのスコアに基づいて適切な結果ページにリダイレクトがかかります。

CSS

CSSで、指定されたIDやクラスを持つ要素に対して様々なスタイルを適用して、見た目を整えます。

button:active, .question__btn button.active {
    background: #707070;
    color: #fff;
}

.question {
    display: block;
    animation: fadeIn 0.8s ease 0s 1 normal;
}
.question__btn button {
    display: inline-flex;
    margin: 0;
}
.question__btn {
    display: flex;
    justify-content: center;
    gap: 40px;
}
p.question__title {
    display: block;
    width: 100%;
    text-align: center;
    position: relative;
}

さいごに

さいごに

今回は、JavaScriptで質問の回答でスコアを出してリダイレクトをかける「診断系」についての解説でした。

見た目はかなり簡素に作っているので、自分好みにカスタマイズして使ってみてください。

UI

  • 他のウィンドウが開くことができないポップアップのUIです。

    モーダル

    モーダル

  • 並列な関係を持つ情報を1つずつ格納するUIです。

    タブ

    タブ

  • サイドから全体を覆うほど大きいメニュー表示するUIです。

    ドロワー

    ドロワー

  • 画像などのコンテンツをスライド表示させるUIです。

    スライダー

    スライダー

  • スクロールで表示が変化するスニペットです。

    スクロール

    スクロール

  • クリックすると隠れていた部分が開閉するUIです。

    アコーディオン

    アコーディオン

  • ページのhタグを取得して目次を生成するスニペットです。

    目次

    目次

  • ページの読み込み時にアニメーションをするスニペットです。

    ローディングアニメーション

    ローディングアニメーション

  • マウスオーバーした際に表示される補足説明です。

    ツールチップ

    ツールチップ

  • ページ内上部にあるナビゲーションUIです。

    ヘッダー

    ヘッダー

  • 行と列の組み合わせでできているUIです。

    テーブル

    テーブル

  • データを表やグラフで可視化して見せるUIです。

    グラフ

    グラフ

  • 背景をアニメーションで動かすスニペットです。

    背景

    背景

  • 短いテキスト情報をスクロール表示するUIです。

    ニュースティッカー

    ニュースティッカー

フォーム

  • ラジオボタン、チェックボックス、ドロップダウンリストなどを通じて、ユーザーが入力できるUIです。

    フォーム

    フォーム

文字

  • 文字列をJavaScriptで装飾・動きをつけるスニペットです。

    文字の装飾

    文字の装飾

  • 文字列の操作をして、置換・変更を行うスニペットです。

    文字の操作

    文字の操作

  • 文字列をカウントして表示などを行うスニペットです。

    文字のカウント

    文字のカウント

  • 数字の要素を取得して、変更するスニペットです。

    数字の操作

    数字の操作

ウィンドウ

classの操作

  • 要素を取得して、classを追加・削除するスニペットです。

    classの操作

    classの操作

要素の操作

API

  • WordPressのAPIを取得して表示するスニペットです。

    WP REST API

    WP REST API

  • Google Books APIsで書籍の情報を表示するスニペットです。

    Google Books APIs

    Google Books APIs

  • 楽天市場のAPIを取得して表示するスニペットです。

    楽天市場API

    楽天市場API

  • openBDのAPIを取得して表示するスニペットです。

    openBD

    openBD

画像・動画

  • 画像を取得して、アニメーションなどの変化を加えるスニペットです。

    画像の操作

    画像の操作

  • YouTubeの動画を表示するスニペットです。

    YouTube

    YouTube

リンク

  • ページ内のリンクを取得して変更・操作するスニペットです。

    リンク

    リンク

  • Google Analyticsとの連携をするスニペットです。

    Google Analytics

    Google Analytics

cookie

  • ブラウザのcookieを利用するスニペットです。

    cookie

    cookie

検索

  • 指定した要素の中から検索を行うスニペットです。

    検索

    検索