document.createElement()したやつは繰り返しappendできない

結論から言うとelement.cloneNode(true);してコピーします。

現象

optionを動的に追加しようとしてて、①すべての選択肢を表示するselect②そのうち条件に当てはまるものだけ表示するselelctを追加したかったんです。

<body>
  ①:<select id="option1"></select>
  ②:<select id="option2"></select>
  <script>
    document.addEventListener("DOMContentLoaded", () => {
      const data = [
        {
          value: 1,
          text: '選択肢1',
          flag: true
        },
        {
          value: 2,
          text: '選択肢2',
          flag: false
        },
        {
          value: 3,
          text: '選択肢3',
          flag: true
        },
      ];

      let options1 = document.createDocumentFragment();
      let options2 = document.createDocumentFragment();

      for (let i = 0, len = data.length; i < len; i++) {
        let option = document.createElement('option');
        option.value = data[i].value;
        option.text = data[i].text;

        if (data[i].flag) {
          options2.appendChild(option);
        }
        options1.appendChild(option);
      }

      document.getElementById('option1').appendChild(options1);
      document.getElementById('option2').appendChild(options2);
    });
  </script>
</body>

f:id:qroku:20190823162202p:plain

②が表示されないー!!!

調べる

      ...
      // こうすると②だけ表示される
      document.getElementById('option1').appendChild(options2); // appendChildを1→2
      document.getElementById('option2').appendChild(options1); // appendChildを1→2
        ...
        // こうしても②だけ表示される
        if (data[i].flag) {
          options1.appendChild(option); // option1に変更
        }
        options2.appendChild(option); // option2に変更
      }

      document.getElementById('option1').appendChild(options1);
      document.getElementById('option2').appendChild(options2);

後からoptionを参照した方が表示されるっぽいですね。

解決策

optionをコピーしたらできました。

      ...
      for (let i = 0, len = data.length; i < len; i++) {
        let option = document.createElement('option');
        option.value = data[i].value;
        option.text = data[i].text;
        
        let option2 = option.cloneNode(true); // これを追加して

        if (data[i].flag) {
          options2.appendChild(option2); // ここをoption2に書き換え
        }
        options1.appendChild(option);
      }
      ...

f:id:qroku:20190823163757p:plain

javascriptむずかしい…