“for .. of”루프를 사용하여 Vanilla JavaScript의 Select 태그에서 옵션 제거

select에서 옵션을 제거하려고 할 때 항상 하나 남은 이유가 무엇입니까?

<select id="form-select">   
<option>111</option>
<option>222</option>
<option>333</option>
</select>

이 JS가 작동하지 않습니다.

var t = document.querySelector('#form-select'); 
for(var i of t.options) {
      t.remove(i.index)
    }

그리고 이것은 또한 작동하지 않습니다 :

for(var i of document.querySelector('#form-select').options) {
  i.remove()
}

나는 그것을 달성 할 수있는 다른 해결책이 있다는 것을 알고 있지만, 그것이 예상대로 작동하지 않는 이유를 이해하고 싶습니다.



답변

.options모음입니다 (불행히도) 라이브 , 그래서 하나씩 라이브 모음의 항목을 통해 반복하고 .remove모든 홀수 하나가 발생합니다 모든 일을 보내고는 유지되고있다. (예, 당신은 첫 번째 항목을 제거 할 때 오른쪽 [0]컬렉션 번째 항목은 바로이 될 것이다 다음 컬렉션의 항목 – 무엇을 사용했는지 [1]될 것이다 [0](그리고 다음에서 다음 인덱스로 이동 일단 [1] 위치에 항목 0은 반복되지 않습니다)

document.querySelectorAll정적 컬렉션을 반환하는 대신 사용하십시오 .

for (const option of document.querySelectorAll('#form-select > option')) {
  option.remove();
}
<select id="form-select">
  <option>111</option>
  <option>222</option>
  <option>333</option>
</select>

요소를 제거하기 전에 (정적) 배열로 펼칠 수도 있습니다.

for (const option of [...document.querySelector('#form-select').options]) {
  option.remove();
}
<select id="form-select">
  <option>111</option>
  <option>222</option>
  <option>333</option>
</select>

또 다른 옵션은 발생 컬렉션이 살아 있기 때문에 작업에이 (가 직관적이지 이후하지만 아마 사용할 수 없습니다)

const { options } = document.querySelector('#form-select');
while (options.length) {
  options[0].remove();
}
<select id="form-select">
  <option>111</option>
  <option>222</option>
  <option>333</option>
</select>


답변

당신은 배열에서 항목을 제거하고 같은 당신이 배열을 반복. 그래서 당신은 :

["one","two","three"]

그런 다음 인덱스 0에서 “1”인 항목을 제거합니다.

["two","three"]

다음으로 인덱스 3에서 “3”인 항목을 제거합니다.

["two"]

인덱스 2에 항목이 없으므로 루프가 중지됩니다.

대신 배열을 반대로 반복하십시오 .

const t = document.querySelector("#form-select")

for (let i = t.options.length-1; i >= 0; i--) {
  t.removeChild(t.options[i])
}
<select id="form-select">
  <option>111</option>
  <option>222</option>
  <option>333</option>
</select>


답변

귀하의 주요 목표는 이것이 일어나는 과정을 이해하는 것이므로 문제를 설명해야합니다.

var arr = ["one", "two", "three", "four", "five", "six"];

for(var i = 0; i < arr.length; i++){
	console.log("i is " + i + ", so we are removing \"" + arr[i] + "\" from " + JSON.stringify(arr) + ".");
	arr.splice(i, 1);
	console.log("After that removal, the array is " + JSON.stringify(arr) + ". We'll now iterate i to " + (i + 1) + " and continue the loop.");
}
console.log("i is too high to grab a value from the array, so we're finished. We're left with " + JSON.stringify(arr) + ".");

이 루프는 “for .. of”루프가 수행하는 것과 동일한 유형의 프로세스를 거쳐 최종 결과에 추가 요소를 남깁니다. 문제는 그것이 반복 될 때 자체 인덱스를 파괴하여 i실제로 참조 하는 값을 변경한다는 것 입니다. 이 문제에 직면하면 배열을 거꾸로 반복 하여 내 파괴의 영향을받지 않습니다.

var arr = ["one", "two", "three", "four", "five", "six"];

for(var i = arr.length - 1; i >= 0; i--){
	console.log("i is " + i + ", so we are removing \"" + arr[i] + "\" from " + JSON.stringify(arr) + ".");
	arr.splice(i, 1);
	console.log("After that removal, the array is " + JSON.stringify(arr) + ". We'll now iterate i to " + (i - 1) + " and continue the loop.");
}
console.log("i is too low to grab a value from the array, so we're finished. We're left with " + JSON.stringify(arr) + ".");

이것이 여기에서 진행되는 일을 완전히 이해하는 데 도움이되기를 바랍니다. 궁금한 점이 있으면 언제든지 의견을 남겨주세요.


답변

배열에서 항목을 제거하면 인덱스가 변경되는 동일한 배열을 반복합니다. 다음은 인덱스없이 옵션을 반복하여 배열에서 제거 할 수있는 샘플입니다.

var selectOptions = document.querySelectorAll('#remove-option>option');
selectOptions.forEach(function(selectOption) {
  selectOption.remove();
  selectOption = null;
});

여기는 바이올린입니다


답변