从动态创建的选项中设置选项"已选择"属性

tsu*_*man 60 javascript jquery select attributes option

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

<select name="country" id="country">
</select>
Run Code Online (Sandbox Code Playgroud)

当执行js函数时,"country"对象是

<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>
Run Code Online (Sandbox Code Playgroud)

并显示"Indonesia"作为默认选择选项.注意:selected="selected"该选项中没有属性.

然后我需要将selected="selected"属性设置为"Indonesia",我使用它

var country = document.getElementById("country");
country.options[country.options.selectedIndex].setAttribute("selected", "selected");
Run Code Online (Sandbox Code Playgroud)

使用萤火虫,我可以看到"印尼"选项是这样的

<option value="ID" selected="selected">Indonesia</option>
Run Code Online (Sandbox Code Playgroud)

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

然后我尝试使用jQuery

$( function() {
    $("#country option:selected").attr("selected", "selected");
});
Run Code Online (Sandbox Code Playgroud)

它在FFX和IE中都失败了.

我需要"Indonesia"选项才能拥有selected="selected"属性所以当我点击重置按钮时,它会再次选择"Indonesia".

更改js功能以动态创建"country"选项不是一种选择.解决方案必须在FFX和IE中都能正常工作.

谢谢

fur*_*ive 105

你是在思考它:

var country = document.getElementById("country");
country.options[country.options.selectedIndex].selected = true;
Run Code Online (Sandbox Code Playgroud)

  • 这不是OP所要求的.OP希望重置按钮起作用. (4认同)

Dav*_*ang 26

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

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

代码抓住了印度尼西亚的选项元素,克隆它并将其放入一个新的div(不在文档中)来检索完整的HTML字符串:<option value="ID">Indonesia</option>.

然后,在将原始选项替换为新选项之前,它会执行字符串替换以将属性添加selected="selected" 为字符串.

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

  • 一个只有javascript的解决方案会更好 (5认同)

ant*_*njs 23

您应该只设置您想要一个select元素的值,而不是修改HTML本身:

$(function() {
    $("#country").val("ID");
});
Run Code Online (Sandbox Code Playgroud)

  • 这不会在选项选项卡中设置所选的html标记 (3认同)

gil*_*ly3 13

这么多错误的答案!

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

  • 复选框或单选按钮: defaultChecked
  • 任何其他<input>控制:defaultValue
  • 下拉列表中的选项: defaultSelected

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

var country = document.getElementById("country");
country.options[country.selectedIndex].defaultSelected = true;
Run Code Online (Sandbox Code Playgroud)

设置defaultSelected每个选项的值可能是个好主意,以防先前设置了一个选项:

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

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


cor*_*dio 11

// 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);??
Run Code Online (Sandbox Code Playgroud)

  • 应该是var $ opt = $('option [value ='+ id +']'); $ opt.attr( '选择', '选择'); (2认同)

Sam*_*fel 9

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

country.options.selectedIndex = index_of_indonesia;
Run Code Online (Sandbox Code Playgroud)

更改"已选择"属性通常不适用于IE.如果你真的想要你正在描述的行为,我建议你编写一个自定义的javascript重置函数,将表单中的所有其他值重置为默认值.


小智 6

这适用于FF,IE9

var x = document.getElementById("country").children[2];
x.setAttribute("selected", "selected");
Run Code Online (Sandbox Code Playgroud)


Rok*_*jan 6

将选项设为默认已选中

HTMLOptionElement.defaultSelected = true;     // JS
$('selector').prop({defaultSelected: true});  // jQuery  
Run Code Online (Sandbox Code Playgroud)

HTMLOptionElement MDN

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

HTMLOptionElement.defaultSelected = true;     // JS
$('selector').prop({defaultSelected: true});  // jQuery  
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

Option 使用 defaultSelected 获取选择的属性

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

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

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

<form>
  <select name="country" id="country"></select>
</form>
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

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


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

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

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

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


不同方法的比较测试

<form>
  <select name="country" id="country"></select>
</form>
Run Code Online (Sandbox Code Playgroud)
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...');
Run Code Online (Sandbox Code Playgroud)

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

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

实际上会使选项被选中

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

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

  • 属性 selected作为命名的Selectedness 状态
  • selected元素对象上的属性,具有布尔值