父级 select 切换后,如何让子级 select 重置为默认选项?
数据小许
父级 select 切换时,需要更新子级选项并重置选中值。只修改 display 不会清除之前选中的 2A。对于这段代码,可以根据父级值重建子级的 option,再选中默认项,这样更容易维护。
为什么仍然显示 2A?
原代码只改变了元素的显示状态,没有设置子级的 value 或 selectedIndex。选项是否显示和它是否被选中是两回事。
原有结构还有几个问题:
- 对于普通原生
select,不应依赖内部的div分组选项和控制显隐,这种写法的解析和显示行为不可靠。 - 两个标记为
selected的all都属于同一个单选select,并非各组独立的默认项。 table-row用于表格行,不适合控制这里的下拉框显示。
根据父级值重建子级选项
保留一个父级 select 和一个子级 select,在 JavaScript 数据中存放选项分组。父级每次变化时,替换子级的全部选项,并显式选中第一项。
下面的代码可以替换原来的 HTML 和联动脚本;脚本放在表单后面:
<form autocomplete="on" method="get" action="my_fun">
<div>
<label for="check">choose:</label>
<select name="check" id="check">
<option value="0" selected>All</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div id="child-row" hidden>
<label for="xxx">子级选项:</label>
<select id="xxx" name="check1" disabled></select>
</div>
</form>
<script>
const parentSelect = document.getElementById("check");
const childSelect = document.getElementById("xxx");
const childRow = document.getElementById("child-row");
const optionsByParent = {
"2": ["2A", "2B"],
"3": ["3A", "3B"]
};
function updateChildSelect() {
const values = optionsByParent[parentSelect.value] || [];
const hasOptions = values.length > 0;
childSelect.replaceChildren();
if (hasOptions) {
childSelect.add(new Option("all", ""));
for (const value of values) {
childSelect.add(new Option(value, value));
}
childSelect.selectedIndex = 0;
}
childRow.hidden = !hasOptions;
childSelect.disabled = !hasOptions;
}
parentSelect.addEventListener("change", updateChildSelect);
updateChildSelect();
</script>
父级从 2 改为 3 时,旧的 2A、2B 会被移除,子级选项变为 all、3A、3B,并立即显示 all。最后一次调用 updateChildSelect() 是为了按父级当前值初始化界面。
只重置选中值时怎么写?
如果现有页面已经能正确替换子级选项,只缺少重置步骤,可以在更新选项后执行:
childSelect.selectedIndex = 0;
这样写要求第一项是所需的默认项。若默认项的 value 唯一且为空字符串,也可以写成:
childSelect.value = "";
原代码中两个 all 都使用空字符串,无法通过 value = "" 区分所属分组,因此应先整理选项结构。
注意提交和事件行为
示例在父级为 0 或 1 时隐藏并禁用子级。disabled 控件不会随表单提交;如果业务要求这些情况下仍提交 check1,需要相应调整。
通过 JavaScript 修改选中值不会自动触发子级的 change 事件。如果其他逻辑监听了该事件,且需要在联动重置时执行,可以在更新完成后显式调用:
childSelect.dispatchEvent(new Event("change", { bubbles: true }));
备注:内容仅供参考。
