ホームページ作成/フォームの活用・装飾 (HTML,CSS,JavaScript)

2段階に連動するプルダウンメニューの作り方(4ページ目)

HTMLで作った2つのプルダウンメニューを、JavaScriptで連動させる方法を解説。メイン(1階層目)のプルダウンメニューの選択項目に応じて、サブ(2階層目)のプルダウンメニューを動的に表示する方法です。2段階に連動させると2階層目の表示項目数を絞れるため、選択肢をシンプルに分かりやすく表示できる効果があります。

西村 文宏

執筆者:西村 文宏

ホームページ作成ガイド

Step3. 連動するプルダウンメニューを表示するJavaScriptを記述

それでは今回のメイン機能である、1階層目のプルダウンメニューの選択項目に連動して2階層目の要素を表示させるJavaScriptを記述しましょう。

1階層目のプルダウンメニューの各項目と、2階層目の要素を連動させるJavaScriptソース:
<script type="text/javascript">
// ▼HTMLの読み込み直後に実行:
document.addEventListener('DOMContentLoaded', function() {

   // ▼全てのプルダウンメニューセットごとに処理
   var mainBoxes = document.getElementsByClassName('pulldownset');
   for( var i=0 ; i<mainBoxes.length ; i++) {
   
      var mainSelect = mainBoxes[i].getElementsByClassName("mainselect");   // 1階層目(メイン)のプルダウンメニュー(※後でvalue属性値を参照するので、select要素である必要があります。)
      mainSelect[0].onchange = function () {
         // ▼同じ親要素に含まれているすべての2階層目(サブ)要素を消す
         var subBox = this.parentNode.getElementsByClassName("subbox");   // 同じ親要素に含まれる.subbox(※select要素に限らず、どんな要素でも構いません。)
         for( var j=0 ; j<subBox.length ; j++) {
            subBox[j].style.display = 'none';
         }
   
         // ▼指定された2階層目(サブ)要素だけを表示する
         if( this.value ) {
            var targetSub = document.getElementById( this.value );   // 「1階層目のプルダウンメニューで選択されている項目のvalue属性値」と同じ文字列をid属性値に持つ要素を得る
            targetSub.style.display = 'inline';
         }
      }
   
   }

});
</script>
上記のソースをHTMLソース内のどこかに記述して下さい。すべてそのままコピー&ペーストするだけで構いません。

前ページまでにご紹介したHTML・CSSソースに上記のスクリプトを加えてブラウザで表示すると、下図で示すように表示されます。1階層目のプルダウンメニューで「市」を選択すると、それに応じた2階層目のプルダウンメニューが連動して表示されて「区」が選べるようになります。

1階層目で「市」を選択すると、連動して2階層目に「区」が出てくる例

1階層目で「市」を選択すると、連動して2階層目に「区」が出てくる例



 

Step3のJavaScriptソースの解説

上記のJavaScriptソースの記述内容を簡単に解説しておきます。すべてコピー&ペーストすれば良いだけなので、以下の解説は必ずしも読む必要はありません。もし、以下に示す共通のclass名を変更した場合は、その部分だけを書き換えて下さい。
  • 1階層目のプルダウンメニューと、2階層目の要素すべてを含む外側のボックスに付加するclass名: pulldownset
  • 1階層目のプルダウンメニューを示すclass名: mainselect
  • 2階層目の要素を示すclass名: subbox

HTMLの読み込み直後に実行:
document.addEventListener('DOMContentLoaded', function() {
   ~~~
});
上記のように記述すると、「~~~」の部分に記述したスクリプトはHTMLソースの読み込み直後に実行されます。ページ上の画像などの読み込みは待たずに、HTMLソースだけが読み込まれた直後に実行されます。なお、「~~~」部分のスクリプトを</body>タグの直前など「処理対象のHTMLソースよりも後」に記述できるなら、この記述は省略しても問題ありません。

(A)「class="pulldownset"」が指定されたすべての要素を得る:
var mainBoxes = document.getElementsByClassName('pulldownset');
上記の記述で、class名が「pulldownset」であるすべての要素(=1階層目と2階層目を含む外側のボックス)がNodeListの形で変数mainBoxesに格納されます。ここで得られた要素1つ1つを対象にして何らかの処理を施すには、for文を使ってループさせます。
for( var i=0 ; i<mainBoxes.length ; i++) {
   ~ 1つ1つに対して実行したい処理 ~
}

(B) Aの中に含まれる要素の内、「class="mainselect"」が指定された要素をすべて得る:
var mainSelect = mainBoxes[i].getElementsByClassName("mainselect");
上記の記述で、先程の(A)の内側に含まれる要素の内、class名が「mainselect」である要素(=1階層目のプルダウンメニュー)がNodeListの形で変数mainSelectに格納されます。

1階層目のプルダウンメニューが変更された際に実行されるスクリプトを書く:
mainSelect[0].onchange = function () {
   ~ 変更された際に実行されるスクリプトソース ~
}
ここでは、1階層目のプルダウンメニューのonchangeイベントを使って、「プルダウンメニューの項目が変更された場合」という条件で実行されるスクリプトを記述しています。

※範囲を(A)の内側に限定しているので、1階層目のプルダウンメニューは1つしか存在しないはずです。したがって、for文を使ってのループは使わずに、「mainSelect[0]」のように添え字「0」を直接記述して、1つ目の要素だけを参照しています。

(C) Bと同じ親要素に含まれる要素の内、「class="subbox"」が指定されたすべての要素を得る:
var subBox = this.parentNode.getElementsByClassName("subbox");
上記の記述で、先程の(B)と同じ親要素に含まれる要素の内、class名が「subbox」である要素(=2階層目の要素)がNodeListの形で変数subBoxに格納されます。

※同一ページ内のすべてを対象にせず、同じ親要素に含まれている要素だけを対象にしている理由は、同一ページ内に複数の「2段階連動プルダウンメニュー」がある場合に無関係なプルダウンメニューを対象に含めてしまわないようにするためです。

とりあえず、Cをすべて非表示にする
for( var j=0 ; j<subBox.length ; j++) {
   subBox[j].style.display = 'none';
}
上記で、2階層目の要素をすべて非表示にしています。

B(=1階層目のプルダウンメニュー)で指定された項目にvalue属性があるかどうかを判断
if( this.value ) {
   ~ 2階層目が指定されている場合の処理 ~
}
この記述は1階層目のプルダウンメニューのonchangeイベント内にありますから、「this」は「1階層目のプルダウンメニュー(select要素)」を示しています。したがって、「this.value」でそのselect要素で選択中のvalue属性値が得られます。ここに文字列があれば「連動する2階層目がある」ことを示し、文字列がなければ「連動する2階層目がない」ことを示します。ここではif文を使って、連動する2階層目がある場合にのみ、以下の処理を実行するよう記述しています。

B(=1階層目のプルダウンメニュー)のvalue属性値と同じid属性値を持つ要素(=2階層目の要素)を得る
var targetSub = document.getElementById( this.value );
ここで、1階層目のプルダウンメニューで選択されている項目のvalue属性値と同じ名称をid属性値に持つ要素(=対応する2階層目の要素)を得て、変数targetSubに格納しています。

それを表示する
targetSub.style.display = 'inline';
対象の要素(=連動する2階層目の要素)のdisplayプロパティの値を「inline」に変更することで、非表示だった要素を表示に切り替えています。なお、インラインではなくブロックレベルでの表示にしたい場合は、上記の「inline」を「block」に書き換えて下さい。

以上で、1階層目のプルダウンメニューで選択された項目と連動する2階層目の要素を表示するスクリプトは完成です。

まとめと補足

解説はここまでです。これ以降では、記述するソースのまとめや補足情報などをご紹介いたします。

【本記事(後半)の目次】
  • 前のページへ
  • 1
  • 3
  • 4
  • 5
  • 8
  • 次のページへ

あわせて読みたい

あなたにオススメ

    表示について

    カテゴリー一覧

    All Aboutサービス・メディア

    All About公式SNS
    日々の生活や仕事を楽しむための情報を毎日お届けします。
    公式SNS一覧
    © All About, Inc. All rights reserved. 掲載の記事・写真・イラストなど、すべてのコンテンツの無断複写・転載・公衆送信等を禁じます