如何选取任意两个HTML节点间的用户可见文本?求完善对应函数
获取两个任意HTML节点间的可见文本
需求:实现一个JavaScript函数,接收两个无关联(不必同属一个DOM子树)的HTML节点firstElement和secondElement,返回它们之间按用户可见顺序排列的文本内容。比如在FAQ页面中,可提取两个问题节点之间的答案文本,示例结果如下:
Yes. We encourage you to go to the Amazon Connect console and set up an Amazon Connect contact center now.
函数实现
// firstElement 和 secondElement 无需关联,不必属于同一子树 function getBetweenElements(firstElement, secondElement) { // 遍历文档,获取所有可见且非空的文本节点(按文档流顺序) const getAllVisibleTextNodes = (root) => { const nodes = []; const walker = document.createTreeWalker( root, NodeFilter.SHOW_TEXT, { acceptNode: node => { const parent = node.parentElement; if (!parent) return NodeFilter.FILTER_REJECT; const style = window.getComputedStyle(parent); // 过滤不可见元素和空白文本 const isVisible = style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0'; const hasContent = node.textContent.trim().length > 0; return isVisible && hasContent ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; } } ); let node; while (node = walker.nextNode()) { nodes.push(node); } return nodes; }; const allTextNodes = getAllVisibleTextNodes(document.body); // 定位第一个元素对应的最后一个文本节点位置 let firstEndIndex = -1; allTextNodes.forEach((node, index) => { if (firstElement.contains(node.parentElement)) { firstEndIndex = index; } }); if (firstEndIndex === -1) return ''; // 定位第二个元素对应的第一个文本节点位置 let secondStartIndex = allTextNodes.length; for (let i = 0; i < allTextNodes.length; i++) { if (secondElement.contains(allTextNodes[i].parentElement)) { secondStartIndex = i; break; } } if (secondStartIndex <= firstEndIndex) return ''; // 提取并拼接中间文本 return allTextNodes.slice(firstEndIndex + 1, secondStartIndex) .map(node => node.textContent.trim()) .join(' '); }
逻辑说明
- 用
TreeWalker遍历整个文档的文本节点,筛选出用户可见(排除display:none、visibility:hidden、opacity:0元素内的文本)且非空白的节点,保证顺序和页面展示一致 - 找到第一个元素包含的所有文本节点的最后位置,以及第二个元素包含的所有文本节点的最前位置
- 提取两个位置之间的所有文本内容,去除多余空白后拼接成结果
内容的提问来源于stack exchange,提问作者Sandeep Gupta
相关产品推荐
相关产品推荐

