导读:本期聚焦于小伙伴创作的《JavaScript实现网页可见HTML节点筛选与字体属性提取全攻略》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript实现网页可见HTML节点筛选与字体属性提取全攻略》有用,将其分享出去将是对创作者最好的鼓励。

如何筛选网页上可见的HTML节点并提取字体信息

在前端开发、页面分析、自动化测试等场景中,我们常常需要筛选出网页上用户可见的HTML节点,并提取这些节点使用的字体相关属性。本文将介绍完整的实现思路与具体代码方案。

一、核心需求分析

要实现可见节点筛选和字体信息提取,需要解决两个核心问题:

  • 如何判断一个HTML节点是否在页面上可见

  • 如何获取节点生效的字体相关样式属性

二、可见性判断规则

一个节点被认为是可见的,需要同时满足以下条件:

  • 节点的宽高均大于0,没有设置 display: none 样式

  • 节点的 visibility 属性不为 hidden

  • 节点的 opacity 大于0

  • 节点没有被其他元素完全遮挡(可选,视场景复杂度决定是否实现)

三、基础实现方案

3.1 判断节点是否可见

我们可以通过 getComputedStyle 方法获取节点的最终计算样式,结合节点的尺寸属性完成可见性判断:

/**
 * 判断HTML节点是否可见
 * @param {HTMLElement} node 待检测的节点
 * @returns {boolean} 是否可见
 */
function isNodeVisible(node) {
  if (!node || !(node instanceof HTMLElement)) {
    return false;
  }
  // 获取计算样式
  const style = window.getComputedStyle(node);
  // 检查display、visibility、opacity
  if (style.display === 'none') return false;
  if (style.visibility === 'hidden') return false;
  if (parseFloat(style.opacity) <= 0) return false;
  // 检查节点尺寸
  const rect = node.getBoundingClientRect();
  if (rect.width <= 0 || rect.height <= 0) return false;
  return true;
}

3.2 提取节点字体信息

字体相关属性同样可以通过 getComputedStyle 获取,常见的字体属性包括 font-family、font-size、font-weight、font-style、line-height 等:

/**
 * 提取节点的字体信息
 * @param {HTMLElement} node 待提取的节点
 * @returns {Object} 字体属性对象
 */
function getNodeFontInfo(node) {
  if (!node || !(node instanceof HTMLElement)) {
    return null;
  }
  const style = window.getComputedStyle(node);
  return {
    fontFamily: style.fontFamily,
    fontSize: style.fontSize,
    fontWeight: style.fontWeight,
    fontStyle: style.fontStyle,
    lineHeight: style.lineHeight,
    letterSpacing: style.letterSpacing
  };
}

3.3 筛选可见节点并提取字体信息

我们可以遍历页面上的所有元素节点,先过滤出可见节点,再批量提取字体信息:

/**
 * 筛选页面可见节点并提取字体信息
 * @returns {Array} 可见节点及其字体信息数组
 */
function getVisibleNodesFontInfo() {
  const allNodes = document.querySelectorAll('*');
  const result = [];
  allNodes.forEach(node => {
    if (isNodeVisible(node)) {
      const fontInfo = getNodeFontInfo(node);
      result.push({
        node: node,
        tagName: node.tagName.toLowerCase(),
        classList: Array.from(node.classList),
        fontInfo: fontInfo
      });
    }
  });
  return result;
}

四、进阶优化

4.1 排除不可见后代节点

上述方案会遍历所有节点,包括可见节点内部不可见的子节点,我们可以添加过滤逻辑,只保留最外层可见节点,或者按需保留所有可见节点:

/**
 * 筛选最外层可见节点(排除可见节点内部的其他可见子节点)
 * @returns {Array} 最外层可见节点数组
 */
function getTopVisibleNodes() {
  const allNodes = Array.from(document.querySelectorAll('*'));
  const visibleNodes = allNodes.filter(node => isNodeVisible(node));
  // 如果节点的父节点也在可见节点列表中,说明该节点是内部节点,排除
  return visibleNodes.filter(node => {
    let parent = node.parentElement;
    while (parent) {
      if (visibleNodes.includes(parent)) {
        return false;
      }
      parent = parent.parentElement;
    }
    return true;
  });
}

4.2 处理节点遮挡场景

如果需要精确判断节点是否被完全遮挡,可以通过 document.elementFromPoint 方法检测节点区域内的元素层级:

/**
 * 增强可见性判断,检查节点是否被完全遮挡
 * @param {HTMLElement} node 待检测的节点
 * @returns {boolean} 是否可见
 */
function isNodeVisibleEnhanced(node) {
  if (!isNodeVisible(node)) return false;
  const rect = node.getBoundingClientRect();
  // 取节点中心点和四个角进行检测
  const points = [
    { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 },
    { x: rect.left + 1, y: rect.top + 1 },
    { x: rect.right - 1, y: rect.top + 1 },
    { x: rect.left + 1, y: rect.bottom - 1 },
    { x: rect.right - 1, y: rect.bottom - 1 }
  ];
  for (const point of points) {
    const topElement = document.elementFromPoint(point.x, point.y);
    // 如果检测到的顶层元素不是当前节点或其后代,说明被遮挡
    if (!node.contains(topElement)) {
      return false;
    }
  }
  return true;
}

五、使用示例

在浏览器控制台中执行以下代码,即可获取页面所有可见节点的字体信息:

// 获取所有可见节点字体信息
const visibleFontList = getVisibleNodesFontInfo();
console.log('可见节点字体信息:', visibleFontList);

// 获取最外层可见节点字体信息
const topVisibleNodes = getTopVisibleNodes();
const topVisibleFontList = topVisibleNodes.map(node => ({
  node: node,
  tagName: node.tagName.toLowerCase(),
  fontInfo: getNodeFontInfo(node)
}));
console.log('最外层可见节点字体信息:', topVisibleFontList);

六、注意事项

  • 遍历所有 * 节点在节点数量较多的页面(如超过1万个节点)可能会有性能损耗,可根据场景缩小遍历范围,比如只遍历特定容器下的节点

  • getComputedStyle 返回的属性值都是字符串格式,如需数值计算需要先进行类型转换

  • 部分节点(如 <script>、<style>、<meta> 等)不会渲染在页面上,遍历时可以提前排除这些标签类型

  • 如果页面有跨域iframe,无法直接访问iframe内部的节点,需要单独处理同源的iframe内容

七、扩展场景

上述方案还可以结合具体需求扩展,例如:

  • 如果需要导出字体信息到本地,可以将结果转换为JSON格式,通过 BlobURL.createObjectURL 生成下载链接,下载地址示例参考 https://www.ipipp.com

  • 如果需要分析特定路径下的字体使用情况,可以修改遍历范围,仅筛选指定容器下的节点,例如 document.querySelector('.content').querySelectorAll('*')

  • 如果需要统计不同字体的使用占比,可以对提取到的 fontFamily 进行去重和计数处理

可见节点筛选字体提取getComputedStyle前端自动化网页分析

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。