You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选网页中包含可见文本的HTML节点

筛选页面实际渲染可见文本节点的实现方案

核心判定逻辑

要排除非实际渲染的文本节点,只需要从渲染根节点出发遍历,过滤掉所有不满足可见条件的节点即可,不需要额外限制视口位置:

  • 直接从document.body开始遍历,天然跳过<head>内的<title>、<meta>、<script>等默认不在页面渲染的标签
  • 过滤CSS属性导致不可见的元素:display: none、visibility: hidden、opacity: 0、宽高为0且overflow: hidden的元素及其子节点
  • 跳过纯空白、无实际文本内容的文本节点

可直接运行的实现代码

使用TreeWalker遍历文本节点的效率远高于全量DOM遍历,适合在Chrome扩展中使用:

/**
 * 获取页面所有实际渲染的可见文本节点
 * @returns {Text[]} 可见文本节点集合
 */
function getVisibleTextNodes() {
  const visibleNodes = [];
  const excludeTags = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEMPLATE']);

  const walker = document.createTreeWalker(
    document.body,
    NodeFilter.SHOW_TEXT,
    {
      acceptNode(node) {
        // 跳过无实际内容的空白文本
        if (!node.textContent.trim()) return NodeFilter.FILTER_REJECT;
        const parent = node.parentElement;
        if (!parent || excludeTags.has(parent.tagName)) return NodeFilter.FILTER_REJECT;

        const style = window.getComputedStyle(parent);
        const rect = parent.getBoundingClientRect();
        // 判定不可见场景
        if (
          style.display === 'none' ||
          style.visibility === 'hidden' ||
          Number(style.opacity) === 0 ||
          (rect.width === 0 && rect.height === 0 && style.overflow === 'hidden')
        ) {
          return NodeFilter.FILTER_REJECT;
        }

        return NodeFilter.FILTER_ACCEPT;
      }
    }
  );

  let node;
  while (node = walker.nextNode()) {
    visibleNodes.push(node);
  }
  return visibleNodes;
}

提取实际使用字体的逻辑:

// 聚合所有可见文本使用的字体
const usedFontSet = new Set();
getVisibleTextNodes().forEach(textNode => {
  const font = window.getComputedStyle(textNode.parentElement).fontFamily;
  usedFontSet.add(font);
});

// 最终结果:所有实际被可见文本使用的字体
const allUsedFonts = Array.from(usedFontSet);

补充说明

  • 该方案不会限制节点必须在当前视口内,页面任意滚动位置的可见元素都会被识别
  • 如果需要统计伪元素(::before/::after)通过content属性渲染的文本,可以额外遍历所有DOM节点,获取伪元素的计算样式补充到结果中
  • 如果需要覆盖transform: scale(0)、clip-path裁剪隐藏等特殊隐藏场景,可以在判定规则中补充对应的检测逻辑,比如检测元素getBoundingClientRect()返回的宽高是否为0即可覆盖大部分缩放隐藏的场景

内容的提问来源于stack exchange,提问作者bugsyb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 06:33:29