Javascript 从动态创建的选项中设置选项“selected”属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4590311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:07:35  来源:igfitidea点击:

set option "selected" attribute from dynamic created option

javascriptjqueryselectattributesoption

提问by tsurahman

I have a dynamically created select option using a javascript function. the select object is

我有一个使用 javascript 函数动态创建的选择选项。选择的对象是

<select name="country" id="country">
</select>

when the js function is executed, the "country" object is

当 js 函数执行时,“国家”对象是

<select name="country" id="country">
    <option value="AF">Afghanistan</option>
    <option value="AL">Albania</option>
    ...
    <option value="ID">Indonesia</option>
    ...
    <option value="ZW">Zimbabwe</option>
</select>

and displaying "Indonesia" as default selected option. note : there is no selected="selected"attribute in that option.

并显示“印度尼西亚”作为默认选择的选项。注意:selected="selected"该选项中没有属性。

then I need to set selected="selected"attribute to "Indonesia", and I use this

然后我需要将selected="selected"属性设置为“印度尼西亚”,我使用这个

var country = document.getElementById("country");
country.options[country.options.selectedIndex].setAttribute("selected", "selected");

using firebug, I can see the "Indonesia" option is like this

使用萤火虫,我可以看到“印度尼西亚”选项是这样的

<option value="ID" selected="selected">Indonesia</option>

but it fails in IE (tested in IE 8).

但它在 IE 中失败(在 IE 8 中测试)。

and then I have tried using jQuery

然后我尝试使用 jQuery

$( function() {
    $("#country option:selected").attr("selected", "selected");
});

it fails both in FFX and IE.

它在 FFX 和 IE 中都失败了。

I need the "Indonesia" option to have selected="selected"attribute so when I click reset button, it will select "Indonesia" again.

我需要“印度尼西亚”选项具有selected="selected"属性,因此当我单击重置按钮时,它将再次选择“印度尼西亚”。

changing the js function to dynamically create "country" options is not an option. the solution must work both in FFX and IE.

更改 js 函数以动态创建“国家/地区”选项不是一种选择。该解决方案必须同时适用于 FFX 和 IE。

thank you

谢谢你

采纳答案by David Tang

Good question. You will need to modify the HTML itself rather than rely on DOM properties.

好问题。您将需要修改 HTML 本身而不是依赖 DOM 属性。

var opt = $("option[val=ID]"),
    html = $("<div>").append(opt.clone()).html();
html = html.replace(/\>/, ' selected="selected">');
opt.replaceWith(html);

The code grabs the option element for Indonesia, clones it and puts it into a new div (not in the document) to retrieve the full HTML string: <option value="ID">Indonesia</option>.

该代码抓住选项元素印尼,克隆它,并把它放到一个新的div(文档不是)来获取完整的HTML字符串:<option value="ID">Indonesia</option>

It then does a string replace to add the attribute selected="selected"as a string, before replacing the original option with this new one.

然后它执行字符串替换以将属性添加selected="selected"为字符串,然后用这个新选项替换原始选项。

I tested it on IE7. See it with the reset button working properly here: http://jsfiddle.net/XmW49/

我在 IE7 上测试过。在这里看到重置按钮正常工作:http: //jsfiddle.net/XmW49/

回答by furtive

You're overthinking it:

你想多了:

var country = document.getElementById("country");
country.options[country.options.selectedIndex].selected = true;

回答by antonjs

Instead of modifying the HTML itself, you should just set the value you want from the relative option element:

而不是修改 HTML 本身,你应该只从相对选项元素中设置你想要的值:

$(function() {
    $("#country").val("ID");
});

In this case "ID" is the value of the option "Indonesia"

在这种情况下,“ID”是选项“印度尼西亚”的值

回答by gilly3

So many wrong answers!

这么多错误的答案!

To specify the value that a form field should revert to upon resetting the form, use the following properties:

要指定表单字段在重置表单时应恢复的值,请使用以下属性:

  • Checkbox or radio button: defaultChecked
  • Any other <input>control: defaultValue
  • Option in a drop down list: defaultSelected
  • 复选框或单选按钮: defaultChecked
  • 任何其他<input>控件:defaultValue
  • 下拉列表中的选项: defaultSelected

So, to specify the currently selected option as the default:

因此,要将当前选定的选项指定为默认值:

var country = document.getElementById("country");
country.options[country.selectedIndex].defaultSelected = true;

It may be a good idea to set the defaultSelectedvalue for every option, in case one had previously been set:

defaultSelected为每个选项设置值可能是一个好主意,以防之前已设置:

var country = document.getElementById("country");
for (var i = 0; i < country.options.length; i++) {
    country.options[i].defaultSelected = i == country.selectedIndex;
}

Now, when the form is reset, the selected option will be the one you specified.

现在,当表单重置时,所选选项将是您指定的选项。

回答by corradio

// get the OPTION we want selected
var $option = $('#SelectList').children('option[value="'+ id +'"]');
// and now set the option we want selected
$option.attr('selected', true);??

回答by Sam Dufel

What you want to do is set the selectedIndex attribute of the select box.

您要做的是设置选择框的 selectedIndex 属性。

country.options.selectedIndex = index_of_indonesia;

Changing the 'selected' attribute will generally not work in IE. If you reallywant the behavior you're describing, I suggest you write a custom javascript reset function to reset all the other values in the form to their default.

更改 'selected' 属性通常在 IE 中不起作用。如果你真的想要你所描述的行为,我建议你编写一个自定义的 javascript 重置函数来将表单中的所有其他值重置为默认值。

回答by Qubiqious

This works in FF, IE9

这适用于 FF、IE9

var x = document.getElementById("country").children[2];
x.setAttribute("selected", "selected");

回答by Ben

// Get <select> object
var sel = $('country');

// Loop through and look for value match, then break
for(i=0;i<sel.length;i++) { if(sel.value=="ID") { break; } }

// Select index 
sel.options.selectedIndex = i;

Begitu loh.

贝吉图洛。

回答by Roko C. Buljan

Make option defaultSelected

将选项设为默认已选中

HTMLOptionElement.defaultSelected = true;     // JS
$('selector').prop({defaultSelected: true});  // jQuery  

HTMLOptionElement MDN

HTMLOptionElement MDN

If the SELECT element is already added to the document (statically or dynamically), to set an option to Attribute-selectedand to make it survivea HTMLFormElement.reset()- defaultSelectedis used:

如果已将 SELECT 元素添加到文档中(静态或动态),则将选项设置为 Attribute-selected并使其保留在a HTMLFormElement.reset()-defaultSelected中:

const EL_country = document.querySelector('#country');
EL_country.value = 'ID';   // Set SELECT value to 'ID' ("Indonesia")
EL_country.options[EL_country.selectedIndex].defaultSelected = true; // Add Attribute selected to Option Element

document.forms[0].reset(); // "Indonesia" is still selected
<form>
  <select name="country" id="country">
    <option value="AF">Afghanistan</option>
    <option value="AL">Albania</option>
    <option value="HR">Croatia</option>
    <option value="ID">Indonesia</option>
    <option value="ZW">Zimbabwe</option>
  </select>
</form>

The above will also work if you build the options dynamically, and than (only afterwards) you want to set one option to be defaultSelected.

如果您动态构建选项,并且(仅在之后)您希望将一个选项设置为,则上述内容也将起作用defaultSelected

const countries = {
  AF: 'Afghanistan',
  AL: 'Albania',
  HR: 'Croatia',
  ID: 'Indonesia',
  ZW: 'Zimbabwe',
};

const EL_country = document.querySelector('#country');

// (Bad example. Ideally use .createDocumentFragment() and .appendChild() methods)
EL_country.innerHTML = Object.keys(countries).reduce((str, key) => str += `<option value="${key}">${countries[key]}</option>`, ''); 

EL_country.value = 'ID';
EL_country.options[EL_country.selectedIndex].defaultSelected = true;

document.forms[0].reset(); // "Indonesia" is still selected
<form>
  <select name="country" id="country"></select>
</form>

Option gets Attribute selected by using defaultSelected

Option 使用 defaultSelected 获取选择的属性

Make option defaultSelected while dynamically creating options

动态创建选项时将选项设为 defaultSelected

To make an option selectedwhile populating the SELECT Element, use the Option()constructor MDN

selected在填充 SELECT 元素时进行选择,请使用Option()构造函数MDN

var optionElementReference = new Option(text, value, defaultSelected, selected);

var optionElementReference = new Option(text, value, defaultSelected, selected);

const countries = {
  AF: 'Afghanistan',
  AL: 'Albania',
  HR: 'Croatia',
  ID: 'Indonesia',     // <<< make this one defaultSelected
  ZW: 'Zimbabwe',
};

const EL_country = document.querySelector('#country');
const DF_options = document.createDocumentFragment();

Object.keys(countries).forEach(key => {
  const isIndonesia = key === 'ID';  // Boolean
  DF_options.appendChild(new Option(countries[key], key, isIndonesia, isIndonesia))
});

EL_country.appendChild(DF_options);

document.forms[0].reset(); // "Indonesia" is still selected
<form>
  <select name="country" id="country"></select>
</form>

In the demo above Document.createDocumentFragmentis used to prevent rendering elements inside the DOM in a loop. Instead, the fragment (containing all the Options) is appended to the Select only once.

在上面的演示中Document.createDocumentFragment用于防止在循环中渲染 DOM 内部的元素。相反,片段(包含所有选项)仅附加到 Select 一次。



SELECT.value vs.OPTION.setAttribute vs.OPTION.selected vs.OPTION.defaultSelected

SELECT.value vs.OPTION.setAttribute vs.OPTION.selected vs.OPTION.defaultSelected

Although some (older) browsers interpret the OPTION's selectedattribute as a "string"state, the WHATWG HTML Specifications html.spec.whatwg.orgstate that it should represent a Boolean selectedness

尽管一些(较旧的)浏览器将 OPTION 的selected属性解释为“字符串”状态,但WHATWG HTML 规范html.spec.whatwg.org声明它应该表示布尔选择

The selectedness of an option element is a boolean state, initially false. Except where otherwise specified, when the element is created, its selectedness must be set to true if the element has a selected attribute.
html.spec.whatwg.org - Option selectedness

一个选项元素的选择是一个布尔状态,最初是假的。除非另有说明,否则在创建元素时,如果元素具有 selected 属性,则其选择性必须设置为 true。
html.spec.whatwg.org - 选项选择

one can correctlydeduce that just the name selectedin <option value="foo" selected>is enough to set a truthy state.

一个可以正确地推断只是名字selected<option value="foo" selected>就足以建立一个truthy状态。



Comparison test of the different methods

不同方法的比较测试

const EL_select = document.querySelector('#country');
const TPL_options = `
  <option value="AF">Afghanistan</option>
  <option value="AL">Albania</option>
  <option value="HR">Croatia</option>
  <option value="ID">Indonesia</option>
  <option value="ZW">Zimbabwe</option>
`;

// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver
const mutationCB = (mutationsList, observer) => {
  mutationsList.forEach(mu => {
    const EL = mu.target;
    if (mu.type === 'attributes') {
      return console.log(`* Attribute ${mu.attributeName} Mutation. ${EL.value}(${EL.text})`);
    }
  });
};

// (PREPARE SOME TEST FUNCTIONS)

const testOptionsSelectedByProperty = () => {
  const test = 'OPTION with Property selected:';
  try {
    const EL = [...EL_select.options].find(opt => opt.selected);
    console.log(`${test} ${EL.value}(${EL.text}) PropSelectedValue: ${EL.selected}`);
  } catch (e) {
    console.log(`${test} NOT FOUND!`);
  }
} 

const testOptionsSelectedByAttribute = () => {
  const test = 'OPTION with Attribute selected:'
  try {
    const EL = [...EL_select.options].find(opt => opt.hasAttribute('selected'));
    console.log(`${test} ${EL.value}(${EL.text}) AttrSelectedValue: ${EL.getAttribute('selected')}`);
  } catch (e) {
    console.log(`${test} NOT FOUND!`);
  }
} 

const testSelect = () => {
  console.log(`SELECT value:${EL_select.value} selectedIndex:${EL_select.selectedIndex}`);
}

const formReset = () => {
  EL_select.value = '';
  EL_select.innerHTML = TPL_options;
  // Attach MutationObserver to every Option to track if Attribute will change
  [...EL_select.options].forEach(EL_option => {
    const observer = new MutationObserver(mutationCB);
    observer.observe(EL_option, {attributes: true});
  });
}

// -----------
// LET'S TEST! 

console.log('\n1. Set SELECT value');
formReset();
EL_select.value = 'AL'; // Constatation: MutationObserver did NOT triggered!!!!
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();

console.log('\n2. Set HTMLElement.setAttribute()');
formReset();
EL_select.options[2].setAttribute('selected', true); // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();

console.log('\n3. Set HTMLOptionElement.defaultSelected');
formReset();
EL_select.options[3].defaultSelected = true; // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();

console.log('\n4. Set SELECT value and HTMLOptionElement.defaultSelected');
formReset();
EL_select.value = 'ZW'
EL_select.options[EL_select.selectedIndex].defaultSelected = true; // MutationObserver triggers
testOptionsSelectedByProperty();
testOptionsSelectedByAttribute();
testSelect();

/* END */
console.log('\n*. Getting MutationObservers out from call-stack...');
<form>
  <select name="country" id="country"></select>
</form>

Although the test 2.using .setAttribute()seems at first the best solution since both the Element Property and Attribute are unison, it can lead to confusion, specially because .setAttributeexpects two parameters:

尽管测试 2.using.setAttribute()起初似乎是最好的解决方案,因为 Element Property 和 Attribute 是一致的,但它可能会导致混淆,特别是因为.setAttribute需要两个参数:

EL_select.options[1].setAttribute('selected', false);
// <option value="AL" selected="false"> // But still selected!

will actually make the option selected

实际上会使选项被选中

Should one use .removeAttribute()or perhaps .setAttribute('selected', ???)to another value? Or should one read the state by using .getAttribute('selected')or by using .hasAttribute('selected')?

应该使用.removeAttribute()还是使用.setAttribute('selected', ???)另一个值?还是应该通过 using.getAttribute('selected')或 using 来读取状态.hasAttribute('selected')

Instead test 3. (and 4.) using defaultSelectedgives the expected results:

而是测试 3.(和 4.) usingdefaultSelected给出了预期的结果

  • Attributeselectedas a named Selectedness state.
  • Propertyselectedon the Element Object, with a Boolean value.
  • 属性selected作为命名的Selectedness 状态
  • selected元素对象上的属性,具有布尔值

回答by Oumaya Abdelkhalek

select = document.getElementById('selectId');
var opt = document.createElement('option');
    opt.value = 'value';
    opt.innerHTML = 'name';
    opt.selected = true;
    select.appendChild(opt);