0

0

JavaScript 解析自定义字体 CSS 文件提取字体权重教程

花韻仙語

花韻仙語

发布时间:2025-12-02 13:39:06

|

200人浏览过

|

来源于php中文网

原创

JavaScript 解析自定义字体 CSS 文件提取字体权重教程

本文详细介绍如何使用 javascript 动态解析用户上传的自定义字体 css 文件,以识别其中包含的所有 `font-weight` 值。我们将利用 `cssstylesheet` api 读取 css 文本、遍历 `@font-face` 规则,并准确提取所需的字体权重信息,为前端编辑器或自定义字体功能提供数据支持。

理解 @font-face 规则与字体权重

在 Web 开发中,@font-face CSS 规则允许开发者指定自定义字体,即使该字体未安装在用户的计算机上。一个完整的 @font-face 规则通常包含 font-family、src、font-style 和 font-weight 等属性。其中,font-weight 属性定义了字体的粗细,可以是数字值(如 100 到 900,步长为 100)或关键字(如 normal、bold)。

当用户上传一个包含多个 @font-face 声明的 CSS 文件时,每个声明可能对应同一字体的不同粗细或样式变体。为了在前端编辑器中为用户提供正确的字体粗细选项,我们需要解析这些 CSS 规则,动态地获取所有可用的 font-weight 值。

使用 JavaScript CSSStyleSheet API 解析 CSS

JavaScript 提供了 CSSStyleSheet API,它允许我们以编程方式创建、修改和解析 CSS 样式表。这个 API 是处理动态 CSS 内容的强大工具,尤其适用于解析用户提供的 CSS 字符串。

核心步骤如下:

立即学习Java免费学习笔记(深入)”;

医真AI+开放平台
医真AI+开放平台

医真AI+ 医学AI开放平台

下载
  1. 创建 CSSStyleSheet 实例: 使用 new CSSStyleSheet() 创建一个新的样式表对象。
  2. 同步替换 CSS 内容: 使用 replaceSync(cssText) 方法将用户提供的 CSS 文本解析并加载到样式表中。这是一个同步操作,适用于处理已知且不依赖于 DOM 渲染的 CSS 字符串。
  3. 遍历 CSS 规则: 通过 cssSheet.cssRules 属性获取样式表中的所有 CSS 规则。这是一个 CSSRuleList 对象,可以转换为数组进行遍历。
  4. 识别 @font-face 规则: 每个 CSS 规则都有一个 type 属性。对于 @font-face 规则,其 type 值为 5。
  5. 提取 font-weight 属性: 对于识别出的 @font-face 规则,可以通过 rule.style.getPropertyValue("font-weight") 方法获取其 font-weight 值。

实现步骤与示例代码

以下是一个完整的 JavaScript 解决方案,演示如何从给定的 CSS 文本中提取所有 font-weight 值。

/**
 * 模拟用户上传的 CSS 文件内容
 */
const cssText = `
  /* latin */
  @font-face {
    font-family: 'Poppins';
    font-style: italic;
    font-weight: 200;
    font-display: swap;
    src: url(https://fonts.gstatic.com/s/poppins/v20/pxiDyp8kv8JHgFVrJJLmv1pVF9eOYktMqg.woff2) format('woff2');
  }

  /* devanagari */
  @font-face {
    font-family: 'Poppins';
    font-style: italic;
    font-weight: 300;
    font-display: swap;
    src: url(https://fonts.gstatic.com/s/poppins/v20/pxiDyp8kv8JHgFVrJJLm21lVFteOYktMqlap.woff2) format('woff2');
  }

  /* latin */
  @font-face {
    font-family: 'Poppins';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url(https://fonts.gstatic.com/s/poppins/v20/pxiGyp8kv8JHgFVrJJLucHtAOvWDSA.woff2) format('woff2');
  }

  /* latin-ext */
  @font-face {
    font-family: 'Agdasima';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url(https://fonts.gstatic.com/s/agdasima/v2/PN_0Rfyxp2f1fUCgAPCGgCza3v3xzHMj54Y.woff2) format('woff2');
  }

  /* 其他 CSS 规则,例如 body 样式 */
  body {
    margin: 0;
    padding: 0;
  }
`;

/**
 * 从 CSS 文本中提取所有 @font-face 规则的 font-weight
 * @param {string} cssContent 用户上传的 CSS 文件的文本内容
 * @returns {number[]} 包含所有唯一 font-weight 值的数组
 */
function getFontWeightsFromCss(cssContent) {
  const cssSheet = new CSSStyleSheet();
  try {
    // 同步解析 CSS 文本
    cssSheet.replaceSync(cssContent);
  } catch (error) {
    console.error("解析 CSS 文本时发生错误:", error);
    return []; // 解析失败则返回空数组
  }

  const fontWeights = new Set(); // 使用 Set 存储以自动去重

  // 遍历所有 CSS 规则
  for (const rule of cssSheet.cssRules) {
    // 检查规则类型是否为 @font-face (type === 5)
    if (rule.type === CSSRule.FONT_FACE_RULE) { // 或者直接使用数字 5
      const fontWeight = rule.style.getPropertyValue("font-weight");
      if (fontWeight) {
        // 将 font-weight 转换为数字并添加到 Set 中
        // 考虑 'normal' (400) 和 'bold' (700) 关键字
        let numericWeight = parseInt(fontWeight, 10);
        if (isNaN(numericWeight)) {
          if (fontWeight === 'normal') {
            numericWeight = 400;
          } else if (fontWeight === 'bold') {
            numericWeight = 700;
          }
        }
        if (!isNaN(numericWeight)) {
          fontWeights.add(numericWeight);
        }
      }
    }
  }

  // 将 Set 转换为排序后的数组
  return Array.from(fontWeights).sort((a, b) => a - b);
}

// 执行函数并打印结果
const availableFontWeights = getFontWeightsFromCss(cssText);
console.log("提取到的字体权重:", availableFontWeights);
// 预期输出: [200, 300, 400, 700]

代码解释:

  1. cssText 变量模拟了用户上传的 CSS 文件内容。
  2. getFontWeightsFromCss 函数接收 CSS 字符串作为参数。
  3. new CSSStyleSheet() 创建一个内存中的样式表对象。
  4. cssSheet.replaceSync(cssContent) 将提供的 CSS 字符串解析并加载到 cssSheet 中。为了健壮性,这里加入了 try...catch 块来捕获可能的解析错误。
  5. new Set() 用于收集 font-weight 值,其优势在于能够自动去重,确保最终结果中每个权重值只出现一次。
  6. for...of cssSheet.cssRules 迭代样式表中的所有规则。
  7. rule.type === CSSRule.FONT_FACE_RULE (或 rule.type === 5) 判断当前规则是否为 @font-face 规则。
  8. rule.style.getPropertyValue("font-weight") 获取 font-weight 属性的值。
  9. 代码中增加了对 font-weight 关键字(normal 和 bold)的转换处理,将其映射到对应的数字值(400 和 700)。这是因为 CSS 允许使用这些关键字,而通常我们希望得到数字化的权重。
  10. 最后,Array.from(fontWeights).sort() 将 Set 转换为数组并进行升序排序,以提供一个有序且唯一的字体权重列表。

注意事项

  • 浏览器兼容性: CSSStyleSheet API(特别是 replaceSync 方法)在现代浏览器中支持良好,但在一些旧版浏览器中可能存在兼容性问题。在生产环境中使用前,请检查目标浏览器的兼容性列表。
  • 安全性: 如果您允许用户上传任意 CSS 文件,务必对文件内容进行适当的验证和沙箱处理,以防止潜在的跨站脚本(XSS)或其他安全漏洞。尽管 CSSStyleSheet 在内存中操作,不会直接影响当前页面的样式,但解析恶意 CSS 仍然可能带来风险。
  • 错误处理: 提供的示例代码包含了基本的 try...catch 来处理 replaceSync 可能抛出的解析错误。在实际应用中,您可能需要更详细的错误报告机制。
  • 性能: 对于非常大的 CSS 文件,replaceSync 的同步特性可能会阻塞主线程。在处理巨型文件时,可能需要考虑异步解析或其他优化策略,例如将解析操作放在 Web Worker 中。
  • font-weight 关键字: 记住 normal 对应 400,bold 对应 700。在前端界面展示时,可能需要将这些数字值再次映射回更友好的文本描述。
  • 其他字体属性: 除了 font-weight,您还可以使用 rule.style.getPropertyValue() 方法提取 font-family、font-style 等其他 @font-face 属性,以满足更复杂的字体管理需求。

总结

通过利用 JavaScript 的 CSSStyleSheet API,我们可以高效且准确地解析用户上传的自定义字体 CSS 文件,从中提取出所有可用的 font-weight 值。这种方法提供了一种健壮的解决方案,能够为前端编辑器、字体选择器等功能提供动态数据支持,极大地增强了 Web 应用的灵活性和用户体验。在实际应用中,结合适当的错误处理、安全性考量和兼容性检查,可以构建出功能强大且稳定的自定义字体管理系统。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

554

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

732

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

477

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

991

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

657

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

551

2023.09.20

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

CSS教程
CSS教程

共754课时 | 19.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号