用 document.querySelectorAll("#id") 可提取所有重复 ID 元素的文本,因其支持非法但存在的重复 ID 选择;需转为数组后 map 提取 textContent 或 innerText,并清洗空白字符。

用 document.querySelectorAll 提取所有重复 ID 的元素文本
HTML 中 ID 重复是非法的,但现实中常有前端疏忽或模板渲染错误导致多个元素共享同一 id。浏览器只保证 document.getElementById 返回第一个匹配项,所以必须绕过它,改用 CSS 选择器方式提取全部。
关键点在于:ID 在 CSS 选择器中仍可被识别(哪怕语义违规),document.querySelectorAll("#my-id") 能拿到所有同 ID 元素。
- 使用
querySelectorAll而非getElementById,否则永远只拿到一个 - 返回的是
NodeList,需用forEach或扩展运算符转数组才能链式调用map - 若元素含 HTML 标签,用
textContent更安全;若需渲染后纯文本(如忽略display: none内容),用innerText
const items = document.querySelectorAll("#product-name");
const texts = Array.from(items).map(el => el.textContent.trim());
// texts 是包含所有重复 ID 元素文本的数组
处理 class 重复时用 getElementsByClassName 的陷阱
getElementsByClassName 看似适合批量取重复 class,但它返回的是动态 HTMLCollection,不是静态数组 —— 后续 DOM 变更会实时影响该集合长度和内容,遍历时容易漏项或报错。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
更稳的做法是立刻转成数组:
- 不要直接对
getElementsByClassName("price")调用forEach(会报错) - 用
[...document.getElementsByClassName("price")]或Array.from()转静态数组 - 如果 class 名含空格或特殊字符(如
data-item),必须用querySelectorAll(".data-item"),getElementsByClassName不支持
const prices = [...document.getElementsByClassName("price")]
.map(el => el.innerText.replace(/[^0-9.]/g, "")); // 提取纯数字价格
用 XPath 处理嵌套重复结构(如多个 .item 下的 .title)
当重复元素嵌套在相似结构中(例如多个 <div class="item">,每个都有 <code><h3 class="title"></h3>),XPath 比 CSS 更灵活,尤其适合跨层级定位。
- 写法:
document.evaluate('//div[@class="item"]//h3[@class="title"]/text()', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) - 注意:XPath 返回的是快照结果集,需手动循环取
snapshotItem(i) - 若目标是获取整个元素(而非仅文本),去掉
/text(),再用.textContent提取 - 避免在循环里反复调用
document.evaluate,性能差且易出错
const result = document.evaluate('//div[@class="item"]/h3', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
const titles = [];
for (let i = 0; i
<h3>提取后去重或保留重复?取决于业务逻辑</h3>
<p>拿到文本数组后,是否去重不能一概而论。比如商品列表里多个“iPhone 15”可能是真实重复上架;而用户填写表单时多个相同邮箱则大概率是误操作。</p>
- 简单去重:
[...new Set(texts)](只适用于字符串完全一致) - 模糊去重(如忽略空格/大小写):
texts.filter((t, i) => texts.findIndex(s => s.trim().toLowerCase() === t.trim().toLowerCase()) === i) - 保留重复但标记频次:
texts.reduce((acc, t) => ({ ...acc, [t]: (acc[t] || 0) + 1 }), {}) - 最常被忽略的一点:DOM 提取的文本可能含不可见字符(如 、零宽空格),建议统一
.replace(/\s+/g, " ").trim()再处理










