やりたいこと
htmlのセレクトボックスにて、選択肢が大量にある場合、階層的に選択できるようにしたいと考えました。1つ目のセレクトボックスで大分類を選択し、1つ目で中分類、3つ目で末端の項目を選択するイメージです。

質問
下のコードで実現できたと考えていますが(logic="OK")、このままでは案件によってコードの書き換えが必要なので、汎用的にするため、配列で指定できるように改修しました(logic="NG")。しかし、期待していた動作になりません。
当方の理解がどのように間違っているのか。どう直せばいいか。ご教授いただければ幸いです。
当方なりの考察
ソースを「var logic="NG";」としたとき、1つ目のセレクトボックスを操作すると、console.logで「A/B/2」と出力して欲しいところ、「B/C/4」と出力されました。本来、2つ目のセレクトボックスのイベントで出力するログです。
addEventListenerの動作が、当方の期待と異なるのかも知れません。
値渡しや参照渡しと関係あるかと妄想しましたが、解決には至りませんでした。
動作確認方法
下のソースを保存して、ブラウザで開き、
A地域を選択し、B国を選択し、C都市を選択すると、絞り込みができると思います。
ソースが「var logic="OK";」のままで、1つ目のセレクトボックスの選択を変えると、
2つ目のセレクトボックスが影響受けますが、
ソースを「var logic="NG";」に変更し、1つ目のセレクトボックスの選択を変えると、
2つ目のセレクトボックスが影響受けなくなります。
ソースコード
html、javascript
1<!DOCTYPE html>2<html lang="ja">3<body>4<script>5function shiborikomi(name1,name2,n){6console.log(name1+"/"+name2+"/"+n);7 idx=document.getElementsByName(name1)[0].selectedIndex;8 v1= document.getElementsByName(name1)[0].options[idx].value;9 n1= document.getElementsByName(name1)[0].options[idx].text.trim().substr(0,n);10 11 es= document.getElementsByName(name2)[0].getElementsByTagName("option");12 for(i=0;i<es.length;i++){13 n2=es[i].innerText.trim().substr(0,n);14 if(n1==n2 && v1>0){15 es[i].style.display='';16 }else{17 if(document.getElementsByName(name2)[0].selectedIndex==es[i].index){18 document.getElementsByName(name2)[0].selectedIndex=0;19 }20 es[i].style.display='none';21 }22 }23 em= document.getElementsByName(name2)[0];24 const ev=new Event("change",{bubbles:false,cancelable:true});25 em.dispatchEvent(ev);26}27 28var logic="OK";29 30window.addEventListener("DOMContentLoaded",function(){31 if(logic=="OK"){32 name1= "A";33 name2= "B";34 name3= "C";35 shiborikomi(name1,name2,2);36 shiborikomi(name2,name3,4);37 document.getElementsByName(name1)[0].addEventListener("change",function(e){shiborikomi(name1,name2,2)});38 document.getElementsByName(name2)[0].addEventListener("change",function(e){shiborikomi(name2,name3,4)});39 }40 if(logic=="NG"){41 var arr=[[2,"A","B"],[4,"B","C"]];42 for (var i=0;i<arr.length;i++) {43 n=arr[i][0];parent_=arr[i][1];child_=arr[i][2];44 shiborikomi(parent_,child_,n);45 }46 for (var i=0;i<arr.length;i++) {47 n=arr[i][0];parent_=arr[i][1];child_=arr[i][2];48 document.getElementsByName(parent_)[0].addEventListener("change",function(e){shiborikomi(parent_,child_,n)});49 }50 }51});52 53</script>54<br>A地域 55<select name="A">56 <option value="">選択してください</option>57 <option value="1" selected>01:欧米</option>58 <option value="2">02:アジア</option>59</select>60<br>B国 61<select name="B">62 <option value="" >選択してください</option>63 <option value="11" selected>0101:アメリカ</option>64 <option value="12">0102:フランス</option>65 <option value="21">0201:インド</option>66 <option value="22">0202:中国</option>67</select>68<br>C都市 69<select name="C">70 <option value="">選択してください</option>71 <option value="111" selected>010101:ニューヨーク</option>72 <option value="112">010102:ロサンゼルス</option>73 <option value="121">010201:ニース</option>74 <option value="122">010202:パリ</option>75 <option value="211">020101:デリー</option>76 <option value="212">020102:バンガロール</option>77 <option value="221">020201:北京</option>78 <option value="222">020202:香港</option>79</select>80</body></html>
補足情報(FW/ツールのバージョンなど)
当方は、chromeで動作確認しました。

0 コメント