如何在自定义字体css文件中找到可用的字体粗细

z9zf31ra  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(104)

我正在开发一个自定义字体功能,用户可以上传一个.css文件并在我们的编辑器中使用它。为了显示,我需要知道文件中的font-weight,以便我可以在编辑器的下拉列表中显示它们。
请建议一个最好的方法来计算可用于自定义字体的字体宽度。由于用户将上传文件,因此我不会知道字体权重。
用户输入:

/* 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');
}

所需数据:【二百、三百、四百】
寻找JS解决方案

anhgbhbe

anhgbhbe1#

一种方法是将上传的css文本附加到文档样式表中,并通过document.styleSheetscssRules属性检索所有属性。
很明显,在添加新的样式表时-我们不想覆盖当前的应用/页面样式-所以我们需要禁用新的样式表/样式规则

示例:填充<style>元素并将其禁用

/**
 * this would be css content
 * retrieved via fileReader/input
 */
let 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');
  }

  /* 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');
  }

  body {
    font-family: Poppins;
    font-style: italic;
    background: red;
  }
`;

/**
 * populate disabled
 * style element with
 * new css rules for parsing
 */
cssTmp.textContent = cssText;

/**
 * get temporary stylesheet by id
 * and disable it
 * to prevent overriding the app's UI style
 */
let stylesheetTmp = [...document.styleSheets].filter((style) => {
  return style.ownerNode.id == "cssTmp";
})[0];

// disable stylesheet
stylesheetTmp.disabled = true;

/**
 * get @font-face rules
 */
let rules = [...stylesheetTmp.cssRules];
let fontProps = [];
rules.forEach((rule) => {
  let type = rule.type;

  // type 5 is @font-face
  if (type === 5) {
    let fontFamily = rule.style.getPropertyValue("font-family");
    let fontStyle = rule.style.getPropertyValue("font-style");
    let fontWeight = rule.style.getPropertyValue("font-weight");
    fontProps.push({
      fontFamily: fontFamily,
      fontWeight: fontWeight,
      fontStyle: fontStyle
    });
  }
});

console.log(fontProps);
<style id="cssTmp"></style>
<p>Test</p>

工作原理

1.创建一个唯一ID<style>元素,例如“cssTmp”
1.使用上传的CSS内容填充此元素
cssTmp.textContent = cssText
1.通过按指定ID筛选所有文档样式表来选择样式表:

let stylesheetTmp = [...document.styleSheets].filter((style) => {
  return style.ownerNode.id == "cssTmp";
})[0];

1.禁用此样式表:

stylesheetTmp.disabled = true;

1.循环通过cssRules
我们首先需要通过应用spread operator或使用Array.from()方法使样式规则可迭代。

let rules = [...stylesheetTmp.cssRules];

@font-face规则可以通过它们的类型进行筛选-即“5”。只需添加一个console.log(rule)来检查规则对象中包含的所有数据。
很有可能,您可能需要更多的属性值,包括字体样式(常规/斜体)-我们可以在先前定义的对象数组中收集这些数据。
现在,您可以使用检索到的数据填充<select>的选项。

相关问题