如何获取单元素单选按钮组的RadioNodeList以安全设置选中状态
问题
当表单仅包含一个name为test、value为a的单选按钮时,调用frm.test.value = "b"会直接获取该input节点并修改其value属性;而当表单包含两个同name的单选按钮(value分别为a和b)时,调用frm.test.value = "b"会获取RadioNodeList对象,并选中value为b的单选按钮(如果存在)。
请问是否可以获取长度小于2的RadioNodeList对象,从而安全调用myobj.value = "b"来选中对应value的单选按钮(若存在),且不会修改其value属性?
注:不需要检查类型或类似如下的变通方案,希望无需检查单选按钮组的数量,直接从DOM中安全获取RadioNodeList(或等效的实时集合):
const checkRadioValue = (frm, name, value) => frm && frm.querySelectorAll(`[name=${name}]`).forEach(item => item.checked = item.value==value )
答案
可以直接获取到长度小于2的RadioNodeList对象,核心是用HTMLFormElement.elements属性来获取,而非直接通过frm[name]的方式。
frm.elements.test始终会返回RadioNodeList——哪怕对应name的单选按钮只有一个。此时调用frm.elements.test.value = "b",不管单选按钮数量是1还是多个,都会统一执行“选中对应value的单选按钮”的逻辑,绝对不会触发修改单个input节点value属性的情况。
举个实际代码例子:
<form id="myForm"> <input type="radio" name="test" value="a"> </form>
const frm = document.getElementById('myForm'); // 获取RadioNodeList,哪怕长度为1 const radioList = frm.elements.test; // 执行选中操作,不会修改input的value radioList.value = "b"; // 此时因为没有value为b的单选按钮,选中状态不变;如果后续动态添加了value为b的单选按钮,该操作会自动选中它(RadioNodeList是实时集合)
原因很简单:HTMLFormElement.elements返回的是HTMLFormControlsCollection,对于同名的单选按钮,无论数量多少,都会封装成RadioNodeList返回;而frm[name]的行为是只有一个元素时返回元素本身,多个时才返回RadioNodeList。所以通过elements属性获取就能统一拿到RadioNodeList,不用判断数量,直接安全调用value赋值来选中对应选项。
内容的提问来源于stack exchange,提问作者Jan Turoň

