NodeList 和 HTMLCollection 非数组,需转真数组(如 Array.from)才能用 findIndex;未选中时返回 -1;注意 reset 后 checked 状态与初始属性差异。

用 Array.from() 转 NodeList 后再 findIndex()
原生 document.querySelectorAll('input[name="xxx"]') 返回的是 NodeList,它不支持 findIndex()、find() 等数组方法。直接调会报 TypeError: NodeList.prototype.findIndex is not a function。
必须先转成真数组,再找下标:
const radios = document.querySelectorAll('input[name="theme"]');
const selectedIndex = Array.from(radios).findIndex(radio => radio.checked);
如果没选中任何项,selectedIndex 是 -1,这点要主动判断。
-
Array.from(radios)和[...radios]效果一样,但前者更明确、兼容性更好(IE11 也支持) - 别用
radios.indexOf(...)—— NodeList 没这个方法 - 别依赖
radios[i].checked循环手动计数,容易漏判或写错边界
getElementsByName() 返回的集合怎么取下标?
document.getElementsByName("gender") 返回 HTMLCollection,它也不是数组,但支持按数字索引访问(如 collection[0]),所以可以手动遍历找位置:
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
const radios = document.getElementsByName("gender");
let index = -1;
for (let i = 0; i < radios.length; i++) {
if (radios[i].checked) {
index = i;
break;
}
}
注意:HTMLCollection 是“活”的集合(live),但这里只是读取,不影响结果。
- 不能对
radios直接调forEach或findIndex,会报错 - 如果页面里有多个同名
name的 radio(比如跨 form 或动态插入),getElementsByName会把它们全抓进来,下标可能和视觉顺序不一致 - 推荐优先用
querySelectorAll+Array.from,语义更清晰、可控性更强
为什么不能直接用 radio.checked 判断后取 indexOf?
因为 NodeList 和 HTMLCollection 都没有 indexOf 方法。你可能会想写:
// ❌ 错误写法
const radios = document.querySelectorAll('input[name="mode"]');
const idx = radios.indexOf(radios.find(r => r.checked)); // TypeError
这本质是混淆了「集合类型」和「数组类型」。浏览器不会自动帮你转换。
- 即使你用
radios[i]手动循环,也要注意:DOM 更新后(比如 JS 动态勾选),checked属性实时反映 UI 状态,但原始 HTML 的checked属性(hasAttribute('checked'))不会变 —— 这在重置表单逻辑里特别容易踩坑 - 如果一组 radio 分散在不同
<form></form>里,且 name 相同,querySelectorAll仍能一次性拿到全部;而getElementsByName也会全拿,但顺序取决于文档流,不是 DOM 树层级
jQuery 用户怎么安全取下标?
jQuery 对象本身是类数组,有 index() 方法,但要注意传参方式:
const $selected = $('input[name="level"]:checked');
const index = $('input[name="level"]').index($selected);
关键点:第一个选择器必须覆盖整组 radio,第二个参数是当前选中的 jQuery 对象。
- 别写成
$('input[name="level"]:checked').index()—— 这返回0(因为只有一个元素) - 如果没选中,
$selected.length === 0,.index()返回-1,可直接用 - 纯 JS 方案现在已足够简洁,除非项目强依赖 jQuery,否则没必要为这点功能引入库
checked 状态未同步」这个细节:用户点了 reset 按钮,UI 看似恢复默认,但 JS 里 radio.checked 可能还是 true(如果之前 JS 设过),而 radio.hasAttribute('checked') 才代表初始状态。需要下标时,得提前缓存初始选中项索引,而不是每次靠 findIndex 临时算。


















