纯HTML无法实现多条件筛选,所有逻辑必须由JavaScript驱动;结构上用form组织语义、FormData采集状态、data-*属性标记真实值。不用form需手动遍历DOM、处理多选、拼接参数,且DOM变动易致JS失效;form天然支持form.elements、FormData自动处理checkbox/select[multiple]、校验等能力。

纯 HTML 无法实现多条件筛选,所有逻辑必须由 JavaScript 驱动;结构上用 form 组织语义、FormData 采集状态、data-* 属性标记真实值,才是可维护的起点。
为什么必须用 form 而不是 div 包裹筛选项
不用 form 的后果是:你得手动遍历每个 input、判断 type、处理多选、拼 query string——而且一改 DOM 结构,JS 就断。而 form 天然支持:
-
form.elements直接拿到所有控件,包括checkbox和select[multiple] -
new FormData(form)自动忽略未选中的checkbox、合并同名name(如多个brand)、跳过disabled项 -
form.checkValidity()可配合required做基础校验,不用自己写正则
常见错误:把 form 改成 div class="filter-form",然后 JS 里用 document.querySelectorAll('[name]') 硬捞——一旦加个动态渲染的筛选项,name 属性漏了或拼错,整个采集逻辑就失效。
FormData 怎么读取多条件并安全转成参数对象
别在每次筛选时手动拼对象,直接用 FormData 转标准键值对:
const form = document.querySelector('#filter-form');
form.addEventListener('change', applyFilter); // 或 input,视需求而定
function applyFilter() {
const formData = new FormData(form);
const params = Object.fromEntries(formData.entries());
// 注意:同名 checkbox(如 name="brand")只返回最后一个选中值
// 要获取全部,得用 getAll()
const brands = formData.getAll('brand'); // 返回字符串数组
const priceMin = formData.get('price_min') || '';
const priceMax = formData.get('price_max') || '';
}
关键点:
-
formData.entries()对单选/文本框够用;formData.getAll()才能拿到所有勾选的checkbox值 -
price_min和price_max可能为空字符串,需显式判断:if (priceMin !== '' && priceMax !== '') { ... } - 空值不参与过滤,每个条件默认为
true(不限制),避免“一个没填就全隐藏”
前端实时过滤表格时,filter() 回调怎么写才不漏行
必须用单次 filter() 回调合并所有条件,而不是链式调用或嵌套 if。链式 .filter().filter() 会反复创建新数组,中间某次过滤把行筛没了,后续条件就无从判断;嵌套 if 容易漏掉“全部条件都满足”的语义。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
正确做法是:遍历每行时,对每个条件单独计算布尔值,再用 && 连接:
const rows = Array.from(document.querySelectorAll('#product-table tbody tr'));
const visibleRows = rows.filter(row => {
const brandCell = row.cells[0].dataset.brand?.trim() || '';
const categoryCell = row.cells[1].dataset.category?.trim() || '';
const priceCell = parseFloat(row.cells[2].textContent?.trim()) || 0;
const matchesBrand = !brands.length || brands.includes(brandCell);
const matchesCategory = !category || categoryCell === category;
const matchesPrice = !priceMin || !priceMax || (priceCell >= priceMin && priceCell row.style.display = 'none');
visibleRows.forEach(row => row.style.display = '');
注意:
- 每个条件默认返回
true(即“不限制”),避免空输入导致整行被隐藏 - 精确匹配优先用
dataset.*存真实值,比依赖显示文本更可靠 - 仅遍历
tbody tr,确保只操作数据行,不误触表头或分页栏
移动端筛选弹窗里,dialog 怎么用才不踩兼容坑
dialog 是原生语义化弹窗标签,支持 showModal() 和 close(),比手写 div + display: none 更可靠(自动处理焦点捕获、Esc 关闭、点击 backdrop 关闭等)。但注意:
- IE 完全不支持,Safari 15.4+ 才支持
modal属性,上线前得加 polyfill 或降级方案 - 默认不渲染在顶层,需手动调用
showModal()——直接写open属性会跳过模态逻辑,失去遮罩和焦点锁定 - 关闭时建议用
dialog.close()而非dialog.removeAttribute('open'),否则 Safari 可能残留滚动条 - 样式上必须显式设置
backdrop伪元素:dialog::backdrop { background: rgba(0,0,0,0.5); }
最易被忽略的是:弹窗本身不负责请求数据,它只负责收集和格式化参数。常见错误是直接在弹窗里写 fetch(),导致逻辑耦合、难以复用、测试困难——筛选条件应由调用方决定如何使用,比如同步到 URL、存入 localStorage 或传给列表组件。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










