HTML多选仅是用户选择方式,批量操作是业务动作;二者不可混淆,否则导致事件错位、状态不同步、iOS兼容失效等问题。
HTML多选和批量操作不是同一类东西,前者是用户选择方式,后者是业务动作;混淆二者会导致事件监听错位、状态不同步、移动端失效等实际问题。
原生 <select multiple> 或 <input type="checkbox"> 只负责维护“是否被选中”这个 DOM 属性,不会自动调用删除接口、导出函数或提交表单。你看到的“批量删除”按钮,背后一定是 JS 显式绑定了 click 事件并读取了选中项。
<select multiple> 加了 change 监听,却在回调里直接发请求,结果 iOS 上读不到 selectedOptions,返回空数组form.submit() 只会按 name 发送键值对,没有语义层的动作识别select.selectedOptions 是现代浏览器推荐方式,但 Safari 在 iOS 15 及更早版本中返回空数组;而 document.querySelectorAll('input[type="checkbox"]:checked') 虽通用,却容易漏掉 disabled 或动态插入未同步状态的元素。
await new Promise(r => setTimeout(r, 0)) 再读取,或改用 Array.from(select.options).filter(opt => opt.selected)
el.disabled === false,否则权限受限项会被误计入操作总数innerHTML 插入)可能 :checked 匹配成功但 el.checked === false,需手动同步属性前端选中 5 个项,后端收不到数组不是 JS 没传对,而是 name 命名不符合框架解析规则。PHP 要 name="ids[]",Spring Boot 却要 name="ids",Express 默认不支持方括号语法。
立即学习“前端免费学习笔记(深入)”;
app.use(express.urlencoded({ extended: true })) 才能解析 ids[]=1&ids[]=2
批量操作失败时,前端提示“操作失败”毫无意义;用户勾了 200 条,其中 3 条因权限被跳过、2 条 ID 格式非法、1 条已被删除,这些细节全靠前端预校验和后端响应结构兜底。
/^[a-zA-Z0-9_-]{6,32}$/.test(id))、去重([...new Set(ids)])、阈值确认(>50 条弹窗二次提醒)checked 状态,不能依赖用户手动取消——否则下次点“导出”会混入上次残留项