Vanilla JavaScript'te "for .. of" döngüsüyle etiketi seç seçeneğinden kaldırma


10

Seçenekleri seçimden kaldırmaya çalışırken, her zaman bir tane kaldı, neden?

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

Bu JS çalışmıyor:

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

Ve bu da çalışmıyor:

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

Bunu başarmak için başka çözümler olduğunu biliyorum, ama neden olması gerektiği gibi çalışmadığını anlamak istiyorum

Yanıtlar:


7

.optionsKoleksiyon (maalesef) canlı , bu nedenle tek-birer canlı koleksiyonun öğeleri üzerinde yineleme ve .removeher tek tek sonuçlanacaktır her birinde sırasıyla tutuluyor. (Örneğin, ilk öğeyi kaldırmak zaman sağ, [0]koleksiyonun inci öğe hemen olacak bir sonraki koleksiyonunda öğe - eskisi gibi [1]olacak [0](ve daha sonra bir sonraki dizinine gitmek kez [1], yeni pozisyonunda öğe 0 tekrarlanmayacaktır)

document.querySelectorAllBunun yerine statik olan bir koleksiyon döndüren kullanın :

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>

Öğeleri kaldırmadan önce (statik) bir diziye de yayılabilir ::

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>

Koleksiyon canlı olduğu için işe yarayan başka bir seçenek (ancak sezgisel olmadığı için muhtemelen kullanılmamalıdır):

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>


3

Dizi boyunca yineleme yaparken bir dizideki öğeleri kaldırıyorsunuz . Yani:

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

sonra, "bir" olan 0 dizinindeki öğeyi kaldırırsınız:

["two","three"]

daha sonra, "üç" olan dizin 1'deki öğeyi kaldırırsınız:

["two"]

Dizin 2'de öğe yok, bu yüzden döngü durur.

Bunun yerine dizi boyunca tersini yineleyin :

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>


.optionsOlduğu değil sorunun kaynağı olan bir dizi, - daha doğrusu, canlı bir HTMLCollection, bu. Bir dizi olsaydı, statik olurdu ve herhangi bir sorun olmazdı.
CertainPerformance

1
Eğer boyunca yineleme gibi bir diziden unsurları kaldırarak @CertainPerformance yapar ben gösterdik sorun neden olur.
symlink

1
@CertainPerformance Bir HTMLOptionsCollectionnesne bu bağlamda bir dizi gibi davranır.
symlink

2

Ana amacınızın bunun olmasına neden olan süreci anlamak olduğunu görüyorum, bu sizin için sorunu göstermelidir:

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) + ".");

Bu döngü, "for .. of" döngünüzün nihai sonuçta ekstralar bırakması için geçtiği işlemle aynı türden geçer. Sorun şu ki, kendi endekslerini aralarından geçerken yok ediyor, böylece igerçekten atıfta bulunulan değeri değiştiriyor . Bu sorunla karşı karşıya olduğumda, diziyi geriye doğru döngüye sokmayı seviyorum, böylece kendi yıkımdan etkilenmem, şöyle:

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) + ".");

Umarım bu, burada neler olup bittiğini iyice anlamanıza yardımcı olur. Herhangi bir sorunuz varsa, bana bir yorum bırakmaktan çekinmeyin.


0

Öğeyi diziden kaldırdığınızda, dizinin değiştiği dizide dönüyorsunuz. Aşağıda, dizinsiz seçenekler arasında geçiş yapabileceğiniz ve diziden kaldırabileceğiniz örnek yer almaktadır.

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

İşte keman

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.