"के लिए .. पाश" के साथ वेनिला जावास्क्रिप्ट में चयन टैग से विकल्प हटाना


10

जब चयन से विकल्पों को हटाने की कोशिश की जाती है, तो हमेशा एक ही होता है, क्यों?

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

यह जेएस काम नहीं कर रहा है:

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()
}

मुझे पता है कि इसे प्राप्त करने के लिए अन्य समाधान हैं, लेकिन मैं यह समझना चाहूंगा कि यह काम क्यों नहीं कर रहा है क्योंकि यह माना जाता है

जवाबों:


7

.optionsसंग्रह है (दुर्भाग्य से) लाइव , तो लाइव संग्रह के आइटम से अधिक पुनरावृत्ति एक-एक करके और .removeहर एक हर अजीब एक में परिणाम होगा ing रखा जा रहा है। (जैसे, सही है जब आप पहली वस्तु निकालते हैं, तो [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>


3

आप सरणी से आइटम निकाल रहे हैं, जैसा कि आप सरणी के माध्यम से पुनरावृति करते हैं। मतलब आपके पास है:

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

तब आप उस आइटम को इंडेक्स 0 पर हटा देते हैं, जो "एक" है, जो आपको छोड़ रहा है:

["two","three"]

अगली बार आप आइटम को इंडेक्स 1 पर हटा दें, जो कि "तीन," आपको छोड़ रहा है:

["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>


.optionsहै न एक सरणी है, जो समस्या का स्रोत है - बल्कि, यह एक HTMLCollection, जो लाइव है। क्या यह एक सरणी थी, यह स्थिर होगी, और इसमें कोई समस्या नहीं होगी।
— 23

1
@CertainPerformance एक सरणी से तत्वों को हटाने के रूप में आप इसे के माध्यम से पुनरावृत्ति समस्या मैं सचित्र है का कारण बनता है।
— सिमिंक

1
@CertainPerformance एक HTMLOptionsCollectionऑब्जेक्ट इस संदर्भ में एक सरणी की तरह कार्य करता है।
— सिमिंक

2

मैं देखता हूं कि आपका मुख्य लक्ष्य उस प्रक्रिया को समझना है जो ऐसा करने का कारण बनती है, इसलिए यह आपके लिए समस्या का वर्णन करना चाहिए:

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 .." लूप आपको अंतिम परिणाम में एक्स्ट्रा के साथ छोड़ देता है। समस्या यह है कि यह अपने स्वयं के सूचकांक को नष्ट कर रहा है क्योंकि यह उनके माध्यम से पुनरावृत्ति कर रहा है, इस प्रकार उस मूल्य को बदल रहा है जो 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) + ".");

मुझे आशा है कि इससे आपको यह समझने में मदद मिलेगी कि यहाँ क्या हो रहा है। यदि आपके कोई प्रश्न हैं, तो मुझे एक टिप्पणी छोड़ने के लिए स्वतंत्र महसूस करें।


0

आप उसी सरणी के माध्यम से लूप कर रहे हैं, जहां आप सरणी से आइटम को हटाने के बाद सूचकांक बदलते हैं। नीचे नमूना है जहां आप बिना सूचकांक के विकल्पों के माध्यम से लूप कर सकते हैं और इसे सरणी से हटा सकते हैं।

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

यहां पर फिडल है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.