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階層目のプルダウンメニューが連動して表示されて「区」が選べるようになります。
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階層目の要素を表示するスクリプトは完成です。
まとめと補足
解説はここまでです。これ以降では、記述するソースのまとめや補足情報などをご紹介いたします。【本記事(後半)の目次】
- ソースのまとめ (p.5)
- ソースのまとめ(IE8でも動くバージョン) (p.6)
- 補足. 2段階のナビゲーション機能付きプルダウンメニューの作り方 (p.7)