医薬品や化粧品のサイトには診断コンテンツが実装されていることが多いです。
ですが、実際に診断コンテンツを実装しようと思っても、どのように作成して良いか分からないと思います。
「サイトに診断コンテンツをを実装したいが方法が分からない」
「実装にはプラグインが必要なのか」
などと実装方法が分からない方に向けて、本記事ではjQueryを使ってYes/No診断コンテンツを実装する方法をご紹介します。
それではどうぞ。
目次
今回作成する診断ツール
今回作成する診断ツールは以下の内容になります。
質問は2つ
各質問ごとに3つの選択肢のうちから1つだけを選択
診断結果は5パターン
質問に対して「はい」「いいえ」「どちらとも言えない」の中から1つ選択し、
質問①と質問②で選択された回答の組み合わせによって診断結果を切り替えるものになります。
質問内容とその結果の組み合わせは以下になります。
完成形はこちらになります。
Yes/No診断
HTMLファイルを準備
まず元となるHTMLファイルを用意します。
今回は、同一ページ内で質問と結果を切り替える形で作成していきます。
質問内容が2つと結果が5つなので計7つのボックスを用意します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | <html> <head> <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1"> <title>Yes/No診断</title> <link href="css/style.css" rel="stylesheet" media="all"> <script src="js/jquery-3.3.1.min.js"></script> <script src="js/common.js"></script> </head> <body> <div class="wrap"> <div class="title-wrap"> <div class="inner-block"> <h1 class="title"> Yes/No診断 </h1> </div> </div> <div class="diagnose-wrap"> <div class="inner-block"> <div class="btn-wrap"> <button type="button" class="tool-btn start-btn" data-box-link="q1">診断スタート</button> </div> <div class="box-wrap"> <!-- Q1 質問内容① --> <div id="q1" class="box"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> <span class="num">Q1.</span> あなたは猫は<span class="ib">好きですか?</span><span class="small">(一つだけ選択)</span> </h2> <div class="select-wrap"> <button type="button" class="select yes">はい</button> <button type="button" class="select no">いいえ</button> <button type="button" class="select vague">どちらとも言えない</button> </div> <div class="btn-wrap"> <button type="button" data-box-link="q2" class="tool-btn next is-active">次の質問へ</button> </div> </div> <!-- Q2 質問内容② --> <div id="q2" class="box"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> <span class="num">Q2.</span> あなたは犬は<span class="ib">好きですか?</span><span class="small">(一つだけ選択)</span> </h2> <div class="select-wrap"> <button type="button" class="select yes">はい</button> <button type="button" class="select no">いいえ</button> <button type="button" class="select vague">どちらとも言えない</button> </div> <div class="btn-wrap"> <button type="button" class="tool-btn next result is-active">診断結果へ</button> </div> </div> <!-- A1 診断結果① --> <div id="a1" class="box result"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> あなたは動物好きです! </h2> <p class="txt"> 猫も犬も好きなあなたは<br class="sp">動物が好きな人です。 </p> <div class="btn-wrap"> <button type="button" class="tool-btn finish">診断終了</button> </div> </div> <!-- A2 診断結果② --> <div id="a2" class="box result"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> あなたは猫好きです! </h2> <p class="txt"> 猫が好きなあなたは<br class="sp">猫が好きな人です。 </p> <div class="btn-wrap"> <button type="button" class="tool-btn finish">診断終了</button> </div> </div> <!-- A3 診断結果③ --> <div id="a3" class="box result"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> あなたは犬好きです! </h2> <p class="txt"> 犬が好きなあなたは<br class="sp">犬が好きな人です。 </p> <div class="btn-wrap"> <button type="button" class="tool-btn finish">診断終了</button> </div> </div> <!-- A4 診断結果④ --> <div id="a4" class="box result"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> あなたは動物が苦手な人です! </h2> <p class="txt"> 猫も犬も苦手なあなたは<br class="sp">動物が苦手な人です。 </p> <div class="btn-wrap"> <button type="button" class="tool-btn finish">診断終了</button> </div> </div> <!-- A5 診断結果⑤ --> <div id="a5" class="box result"> <span class="close-btn"> <span class="mark"></span> </span> <h2 class="title"> あなたは動物に興味がない人です! </h2> <p class="txt"> これから好きになる<br class="sp">可能性が高いです。 </p> <div class="btn-wrap"> <button type="button" class="tool-btn finish">診断終了</button> </div> </div> </div> </div> </div> </div> </body> </html> |
jQueryの前に、HTMLで必要な記述をそれぞれ説明していきます。
data属性
「診断スタート」ボタンと1つ目の質問の「次の質問へ」ボタンにdata属性を付けます。
この2つにdata属性を持たせる理由は、
「診断スタート」ボタン ⇒ 質問①
質問① ⇒ 質問②
と遷移させる為です。
1 2 3 4 5 6 7 8 9 10 11 | // 診断スタート <div class="btn-wrap"> <button type="button" class="tool-btn start-btn" data-box-link="q1">診断スタート</button> </div> // 次の質問へ <div class="btn-wrap"> <button type="button" data-box-link="q2" class="tool-btn next is-active">次の質問へ</button> </div> |
今回は次のボックスを呼び出すのに使用するので「data-box-link」という名前にします。
呼び出したいボックスに指定したIDを、data属性に持たせます。
HTML5から追加された属性の一つで「カスタムデータ属性」とも呼ばれています。
その名の通りカスタムが可能で、「data-○○」という形で「○○」部分に独自の名前を入れて使うことができます。
主な役割は以下の3つです。
・CSSでのスタイリング
・Javascriptでの値を取得、利用
・jQueryでの値を取得、利用
jQueryで呼び出す
HTMLの準備が整ったらさっそくjQueryの記述をしていきます。
大まかに分けて必要な記述は以下の5点になります。
「診断スタート」を押したら一番最初の質問内容を呼び出す
「次の質問へ」を押したら次の質問内容を呼び出す
選択肢を選択した時
「診断結果へ」を押したら合った診断結果を呼び出す
「診断終了」を押したら診断をやめる
全体のソースは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | $(function () { // スタートボタンがクリックされたら $('.tool-btn').on('click', function () { // クリックした要素のdata属性を取得 var target = $(this).data('box-link'); // 上記で取得した要素と同じID名を持つ要素を取得 var box = $('#' + target); // その要素にclassを付け替える $(box).parent().addClass('is-inactive'); $(box).fadeIn(); $(this).parent().addClass('is-inactive'); }); // 「次の質問へ」がクリックされたら $('.box .tool-btn').on('click', function () { $(this).not($(this).parents('.box').fadeOut(1200)); $(this).parents('.box').toggleClass('is-inactive'); }); // 選択肢がクリックされたら $('.select').on('click', function () { $(this).toggleClass('is-inactive'); $(this).siblings($('.select')).not($(this)).removeClass('is-inactive'); var select = $(this).parents('.box').find('.select'); var toolBtn = $(this).parents('.box').find('.tool-btn.next'); // 選択されていないとボタンをクリックできないようにする if (select.hasClass('is-inactive')) { toolBtn.removeClass('is-inactive'); } else { toolBtn.addClass('is-inactive'); } }); // 診断結果の出し分け $('.tool-btn.result').on('click', function () { // それぞれの選択肢の数を数える var yesCnt = $('.select.yes.is-inactive').length; var noCnt = $('.select.no.is-inactive').length; var vagueCnt = $('.select.vague.is-inactive').length; // 「はい」が2つ以上の時 if (yesCnt >= 2) { $('#a1').fadeIn(); } // 「はい」が1つ かつ 「いいえ」が1つ または「どちらともいえない」が1つの時 else if ((yesCnt == 1) && ((noCnt == 1) || (vagueCnt == 1))) { if($('#q1 .select.yes').hasClass('is-inactive')) { $('#a2').fadeIn(); } else if($('#q2 .select.yes').hasClass('is-inactive')) { $('#a3').fadeIn(); } } // 「いいえ」が2つ以上 または 「いいえ」が1つ かつ 「どちらともいえない」が1つの時 else if ((noCnt >= 2) || ((noCnt == 1) && (vagueCnt == 1))){ $('#a4').fadeIn(); } // 「どちらともいえない」が2つ以上の時 else if (vagueCnt >= 2) { $('#a5').fadeIn(); } }); // 診断を閉じる $('.close-btn, .tool-btn.finish').on('click', function () { $('.box').fadeOut("fast"); $('.select, .btn-wrap, .box-wrap, .box').removeClass('is-inactive'); $('.tool-btn.next').addClass('is-inactive'); }); }); |
「診断スタート」を押したら一番最初の質問内容を呼び出す
診断スタートボタンをクリックしたら一番最初の質問内容を呼び出す記述は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 | // スタートボタンがクリックされたら $('.tool-btn').on('click', function () { // クリックした要素のdata属性を取得 var target = $(this).data('box-link'); // 上記で取得した要素と同じID名を持つ要素を取得 var box = $('#' + target); // その要素にclassを付け替える $(box).parent().addClass('is-inactive'); $(box).fadeIn(); $(this).parent().addClass('is-inactive'); }); |
data属性を取得
1 2 3 4 5 6 | // クリックした要素のdata属性を取得 var target = $(this).data('box-link'); // 上記で取得した要素と同じID名を持つ要素を取得 var box = $('#' + target); |
ここで先程「診断スタート」ボタンと質問①の「次の質問へ」ボタンへ付けたdata属性を使用します。
クラス「tool-btn」をクリックし、その要素に付与されているdata属性を、変数targetに代入します。
取得したdata属性を#を付けて、変数boxの中にIDとして格納します。
これで呼び出す準備は完了です。
変数boxと同じIDを持つ要素にクラスを付与する
1 2 3 4 5 6 | // その要素にclassを付け替える $(box).parent().addClass('is-inactive'); // ① $(box).fadeIn(); // ② $(this).parent().addClass('is-inactive'); // ③ |
①質問や結果のボックスを囲っている親要素にクラス「is-inactive」を付与する
「診断スタート」ボタンを非表示にして、その場所に診断内容を表示させる形にしているので、
親要素であるクラス「box-wrap」にabsoluteを指定しています。
それをクラスを付与させてrelativeに変更させます。
②変数boxと同じIDを持つボックスをフェードインで表示する
③クリックした要素の親要素にクラス「is-inactive」を付与する
「診断スタート」ボタンをクリックした際にクラスを付与して非表示にします。
次の質問へを押したら次の質問へ
1 2 3 4 5 6 7 | // 「次の質問へ」がクリックされたら $('.box .tool-btn').on('click', function () { $(this).not($(this).parents('.box').fadeOut()); $(this).parents('.box').toggleClass('is-inactive'); }); |
「次の質問へ」ボタンがクリックされたら、一度クリックしたボタンがあるボックス以外をフェードアウトします。
クリックしたボタンの親要素のクラス「box」にクラス「is-inactive」を付けはずしして非表示にします。
選択肢
選択肢を選択させる記述は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 選択肢がクリックされたら $('.select').on('click', function () { $(this).toggleClass('is-inactive'); $(this).siblings($('.select')).not($(this)).removeClass('is-inactive'); var select = $(this).parents('.box').find('.select'); var toolBtn = $(this).parents('.box').find('.tool-btn.next'); // 選択されていないとボタンをクリックできないようにする if (select.hasClass('is-inactive')) { toolBtn.removeClass('is-inactive'); } else { toolBtn.addClass('is-inactive'); } }); |
選択肢を選択した時
1 2 3 4 5 6 | $('.select').on('click', function () { $(this).toggleClass('is-inactive'); // ① $(this).siblings($('.select')).not($(this)).removeClass('is-inactive'); // ② }); |
①選択したボタンにクラス「is-inactive」をつけて選択状態にする
クラス「is-inactive」を付与して選択状態にします。
②複数選択が出来ないようにする
今回、選択肢は1つだけ選択する形なので複数選択できないよう、選択した選択肢以外にクラス「is-inactive」が付与されていたら、外す記述を追加します。
未選択の時は遷移しない
未選択が出ないように、選択しないと次へのボタンを押せないようにします。
1 2 3 4 5 6 7 8 9 10 11 | var select = $(this).parents('.box').find('.select'); var toolBtn = $(this).parents('.box').find('.tool-btn.next'); // 選択されていないとボタンをクリックできないようにする if (select.hasClass('is-inactive')) { toolBtn.removeClass('is-inactive'); } else { toolBtn.addClass('is-inactive'); } |
『選択肢が選択されていたら、次の質問ボタンからクラスを外して選択できる状態』にし、
『選択肢が選択されていなかった場合は、次の質問にクラスを付与して選択できない状態』にします。
「診断結果へ」を押したら合った診断結果を呼び出す
結果の出し分けは、質問①と質問②の選択肢の組み合わせで出し分けます。
組み合わせの種類は以下の5つです。
「はい」が2つ以上の時
「はい」が1つ かつ 「いいえ」が1つ、または「どちらとも言えない」が1つの時(質問①の選択肢が「はい」の場合)
「はい」が1つ かつ 「いいえ」が1つ、または「どちらとも言えない」が1つの時(質問②の選択肢が「はい」の場合)
「いいえ」が2つの時 または「いいえ」が1つ かつ 「どちらとも言えない」が1つの時
「どちらとも言えない」が2つの時
全体のコードは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // 診断結果の出し分け $('.tool-btn.result').on('click', function () { // それぞれの選択肢の数を数える var yesCnt = $('.select.yes.is-inactive').length; var noCnt = $('.select.no.is-inactive').length; var vagueCnt = $('.select.vague.is-inactive').length; // 「はい」が2つ以上の時 if (yesCnt >= 2) { $('#a1').fadeIn(); } // 「はい」が1つ かつ 「いいえ」が1つ または「どちらともいえない」が1つの時 else if ((yesCnt == 1) && ((noCnt == 1) || (vagueCnt == 1))) { if($('#q1 .select.yes').hasClass('is-inactive')) { $('#a2').fadeIn(); } else if($('#q2 .select.yes').hasClass('is-inactive')) { $('#a3').fadeIn(); } } // 「いいえ」が2つ以上 または 「いいえ」が1つ かつ 「どちらともいえない」が1つの時 else if ((noCnt >= 2) || ((noCnt == 1) && (vagueCnt == 1))){ $('#a4').fadeIn(); } // 「どちらともいえない」が2つ以上の時 else if (vagueCnt >= 2) { $('#a5').fadeIn(); } }); |
それぞれの選択肢の数を数える
まず、「はい」「いいえ」「どちらとも言えない」の選択肢の個数を数えるために、変数を宣言します。
1 2 3 4 5 | var yesCnt = $('.select.yes.is-inactive').length; // 「はい」の数 var noCnt = $('.select.no.is-inactive').length; // 「いいえ」の数 var vagueCnt = $('.select.vague.is-inactive').length; // 「どちらとも言えない」の数 |
選択した選択肢にはクラス「is-inactive」が付与されます。
それを、lengthプロパティを付けて個数をカウントできるようにします。
この変数をif文で判断して結果を出し分けます。
文字列の長さや配列の要素数などを取得するためのプロパティ
「はい」が2つの時
質問①と質問②のどちらも「はい」を選択した場合の記述は以下になります。
1 2 3 4 5 6 | // 「はい」が2つ以上の時 if (yesCnt >= 2) { $('#a1').fadeIn(); } |
変数yesCntが2つ以上の時に、ID「a1」を持つ診断結果をフェードインで表示させます。
「はい」が1つ かつ 「いいえ」が1つ、または「どちらとも言えない」が1つの時
質問①が「はい」の時
質問②が「はい」の時
こちらは、質問①と質問②のどちらが「はい」なのかによって診断結果が変わります。
1 2 3 4 5 6 7 8 9 10 | // 「はい」が1つ かつ 「いいえ」が1つ または「どちらともいえない」が1つの時 else if ((yesCnt == 1) && ((noCnt == 1) || (vagueCnt == 1))) { if($('#q1 .select.yes').hasClass('is-inactive')) { // 質問①が「はい」の時 $('#a2').fadeIn(); } else if($('#q2 .select.yes').hasClass('is-inactive')) { // 質問②が「はい」の時 $('#a3').fadeIn(); } } |
変数の個数を数えているif文の中に、質問①が「はい」の場合と質問②が「はい」の場合のif文を記述します。
1つ目の質問が「はい」の時
1 2 3 4 5 | if($('#q1 .select.yes').hasClass('is-inactive')) { // 質問①が「はい」の時 $('#a2').fadeIn(); } |
質問①が「はい」の場合、ID「a2」を持つ診断結果を表示させます。
2つ目の質問が「はい」の時
1 2 3 4 5 | else if($('#q2 .select.yes').hasClass('is-inactive')) { // 質問②が「はい」の時 $('#a3').fadeIn(); } |
質問②が「はい」の場合、ID「a3」を持つ診断結果を表示させます。
「いいえ」が2つの時 または「いいえ」が1つ かつ 「どちらとも言えない」が1つの時
1 2 3 4 5 6 | // 「いいえ」が2つ以上 または 「いいえ」が1つ かつ 「どちらともいえない」が1つの時 else if ((noCnt >= 2) || ((noCnt == 1) && (vagueCnt == 1))){ $('#a4').fadeIn(); } |
「いいえ」が2つ以上 または 「いいえ」が1つ かつ 「どちらともいえない」が1つの場合、ID「a4」を持つ診断結果を表示します。
「どちらとも言えない」が2つの時
1 2 3 4 5 6 | // 「どちらともいえない」が2つ以上の時 else if (vagueCnt >= 2) { $('#a5').fadeIn(); } |
質問①と質問②の選択肢が「どちらとも言えない」場合、ID「a5」を持つ診断結果を表示させます。
診断の終了
1 2 3 4 5 6 7 8 | // 診断を閉じる $('.close-btn, .tool-btn.finish').on('click', function () { $('.box').fadeOut("fast"); // // ① $('.select, .btn-wrap, .box-wrap, .box').removeClass('is-inactive'); // ② $('.tool-btn.next').addClass('is-inactive'); // 「次の質問へ」ボタンにクラス「is-inactive」を付ける }); |
①「診断を止める」ボタン、クラス「finish」を持つボタンをクリックしたら、現在開いているボックスをフェードアウトさせる
②診断を進めていく中で、付与されたクラス「is-inactive」を外す
③選択肢を選択した際に、次の質問へボタンから外されたクラス「is-inactive」を再度付与する。
これで最初の状態に戻ります。
まとめ
如何だったでしょうか?
プラグインや特定のjsなどは必要なく、クリックイベントとif文などといった普通のjQueryだけで実装することが出来ます。
ソース全体を見たらどこの記述でどの動きを実装しているか理解しづらいですが、分解して記述を見ていけば簡単に理解できます。
今回は、「はい」「いいえ」「どちらとも言えない」の○×△の結果が分かりやすいものでしたが、
それ以外の選択肢にしたい場合もあると思います。
この選択肢の時は○判定、そうじゃない時は×判定、などと付与されているクラスで判断しているので簡単に自分のサイトにあった内容に出来ると思います。
本記事が、診断コンテンツを実装したい方へのヒントとなれば幸いです。