SELECT[multiple]:selected を取得する方法を発明した?

そもそも SELECT:selected なんてものはない!
そこで change イベントで select[multiple] をすべて監視し、selected になったもに
"data-selected" を付与しておけば、いつでも querySelectorAll で取得できる。
もちろん、クエリーにもそれを付与しなければならないが。

let select =
  document.querySelectorAll (
    'select:not([multiple]), select[multiple] option[data-selected]'
 );

考え方は、select[multiple]を除外してその子要素の option 要素を集める
option 要素の親要素をたどれば select 要素に行き着く。
そこで name を取得すればOK!


Memo:
select.selectedOptions があることを知った。

FORM要素(とは限らない)から、有効な値を取り出すには・・・

これで、 radio, checkbox, select[multiple] から有効な値を取得することができるようになった。

<!DOCTYPE html>
<meta charset="UTF-8" />
<title>Document</title>
<style>
</style>
<body>
<form>
  <p><input name="A" value="a">
  <p><input name="B" value="b" type="hidden">
  <p><output name="C" value="cccc">c</output>
  <p><textarea name="D">d</textarea>
  <p>
    <input name="E" value="e0" type="radio">E0 /
    <input name="E" value="e1" type="radio" checked>E1 /
    <input name="E" value="e2" type="radio">E2
  <p>
    <input name="F" value="f0" type="checkbox" checked>F0 /
    <input name="F" value="f1" type="checkbox">F1 /
    <input name="F" value="f2" type="checkbox" checked>F2
  <p>
    <select name="G">
      <option value="g0">G0</option>
      <option value="g1" selected>G1</option>
      <option value="g2">G2</option>
    </select>
  </p>
  <p>
    <select name="H" multiple id="H">
      <option value="h0" selected>H0</option>
      <option value="h1">H1</option>
      <option value="h2" selected>H2</option>
    </select>
  </p>

  <input type="button" value="Test" onclick="test()">
</form>
<div>
  <textarea id="T" cols="60" rows="30"></textarea>
</div>

<script>

class SurveillanceSELECT {
  constructor (root = document, key) {
    this.root = root;
    this.key = 'data-' + key;
  }

  switch (select) {
    for (let op of select.options) {
     op.selected 
     ? op.setAttribute (this.key, '')
     : op.removeAttribute (this.key);
    }
  }

  setting () {
    Array.from (
      this.root.querySelectorAll ('select[multiple]'),
      sel => this.switch (sel)
    );
  }

  handleEvent (event) {
    let e = event.target;
    if ('select-multiple' === e.type)
      this.switch (e);
  }

  static create (root = document) {
    const key = 'selected';
    let obj = new this (root, key);
    obj.setting ();
    root.addEventListener ('change', obj, false);
    return obj;
  }
}

SurveillanceSELECT.create ();
//_________________________________


function test () {
  const q0 = '*[name]:not([type="checkbox"]):not([type="radio"]):not(select[multiple]),*[name]:checked,select[name][multiple] option[data-selected]';
  let es = document.querySelectorAll (q0);
  T.value = [...es].map(e=>[(e.nodeName == 'OPTION' ? e.parentNode: e).name, e.value].join (" : ")).join (" \n");
}

</script>