SELECT要素の連動(いくつでも可能&iOS Safariで動作可)
連動させると指数関数的に増えるのも理解できる
Ajaxを推めるのも理解できる
しかし、小さいならこれでも吉とするかな。
optgroupに対してdisplay:noneが効くのならもっと簡単なのに。
iPadとかiPhoneのsafariに対応させるために面倒だったなと愚痴をこぼす。
3連動させるとして、最後のselect には、onchange は要らない。
optgroupとoptionが共存する時はoptionを消さない
selectedを指定したい時はclass="selected"をつけることで代用
複数のclassを指定するときは最初にselected
構想を練っているときが楽しい。
<!DOCTYPE html> <meta charset="utf-8"> <title>SELECT要素の連動</title> <style> body { color: white; background: black; } </style> <body> <form id="SELECT_TEST"> <p> <label>Group:</label> <select name="group" class="selectA"> <option value="GroupA">GROUP A</option> <option value="GroupB">GROUP B</option> </select> <label>Team:</label> <select name="team" class="selectA"> <optgroup label="GroupA"> <option value="TeamA">TEAM A</option> <option value="TeamB">TEAM B</option> </optgroup> <optgroup label="GroupB"> <option value="TeamC">TEAM C</option> <option value="TeamD">TEAM D</option> </optgroup> </select> <label>Player:</label> <select name="player" class="selectA"> <optgroup label="TeamA"> <option value="PlayerA">PLAYER A</option> <option value="PlayerB">PLAYER B</option> </optgroup> <optgroup label="TeamB"> <option value="PlayerC">PLAYER C</option> <option value="PlayerD">PLAYER D</option> </optgroup> <optgroup label="TeamC"> <option value="PlayerE">PLAYER E</option> <option value="PlayerF">PLAYER F</option> </optgroup> <optgroup label="TeamD"> <option value="PlayerG">PLAYER G</option> <option value="PlayerH">PLAYER H</option> </optgroup> </select> </p> <p> <label>Group:</label> <select name="group" class="selectB"> <option value="GroupA">GROUP A</option> <option value="GroupB" selected>GROUP B</option> </select> <label>Team:</label> <select name="team" class="selectB"> <optgroup label="GroupA"> <option value="TeamA">TEAM A</option> <option value="TeamB">TEAM B</option> </optgroup> <optgroup label="GroupB"> <option value="TeamC">TEAM C</option> <option value="TeamD" class="selected">TEAM D</option> </optgroup> </select> <label>Player:</label> <select name="player" class="selectB"> <optgroup label="TeamA"> <option value="PlayerA">PLAYER A</option> <option value="PlayerB">PLAYER B</option> </optgroup> <optgroup label="TeamB"> <option value="PlayerC">PLAYER C</option> <option value="PlayerD">PLAYER D</option> </optgroup> <optgroup label="TeamC"> <option value="PlayerE">PLAYER E</option> <option value="PlayerF">PLAYER F</option> </optgroup> <optgroup label="TeamD"> <option value="PlayerG">PLAYER G</option> <option value="PlayerH">PLAYER H</option> </optgroup> </select> </p> <script> (function (D) { function toAry (nodeList) { return Array.prototype.slice.call (nodeList); } function append (e) { this.insertBefore (e, this.firstChild); } function remove (e) { this.removeChild (e); } function replace (e, n) { toAry (e.querySelectorAll ('optgroup')).forEach (remove, e); e.appendChild (n); } //______ function ESelect (select) { this.eSelect = select; this.cSelect = select.cloneNode (true); } function getVal (select) { return select.options[select.selectedIndex].value; } function replaceGroup (label) { var s, e; var g = this.cSelect.querySelector (label ? 'optgroup[label="' + label + '"]' : 'optgroup:first-of-type'); if (g) { replace (e = this.eSelect, g.cloneNode (true)); s = e.querySelector ('option[class^="selected"]') || e.querySelector ('option:first-of-type'); if (s) s.selected = true; } else toAry (this.cSelect.querySelectorAll ('optgroup')) .reverse () .forEach (append, e); } //______ ESelect.prototype.replaceGroup = replaceGroup; ESelect.prototype.getVal = getVal; //______ function selectChangeHandle (event) { var e = event.target; var n, t; while (-1 < (n = this.selectBuffer.indexOf (e))) { t = this.cloneBuffer[n]; t.replaceGroup (getVal (e)); e = t.eSelect; } } function init (select) { var buf = { }, begin = [ ]; var i, s, e, n; for (i = 0; s = select[i]; i += 1) { if ((n = s.className)) { if (e = buf[n]) { e.addEventListener ('change', this, false); this.selectBuffer.push (e); this.cloneBuffer.push (new ESelect (s)); buf[n] = s; } else begin.push (buf[n] = s); } } begin.forEach (function (select) { selectChangeHandle.call (this, { target: select }); }, this); } //______ var Interlock = new Object; Interlock.handleEvent = selectChangeHandle; Interlock.selectBuffer = [ ]; Interlock.cloneBuffer = [ ]; init.call (Interlock, D.querySelectorAll ('select')); }) (document); </script>