如何通过JavaScript提取上传的自定义字体CSS文件中的可用font-weight
提取CSS文件中自定义字体的font-weight值的JavaScript方案
要从用户上传的CSS文件中提取可用的font-weight值,核心思路是定位所有@font-face规则,提取每个规则里的font-weight属性,统一格式后去重排序。以下是两种可靠实现方案:
方案一:正则表达式解析(轻量兼容)
适合处理结构相对规范的CSS,无需依赖浏览器API,代码简洁:
function extractFontWeights(cssText) { // 匹配所有@font-face块 const fontFaceRegex = /@font-face\s*{([^}]*)}/g; // 匹配font-weight属性值 const fontWeightRegex = /font-weight\s*:\s*(\d+|normal|bold|bolder|lighter)\s*;/i; const weights = new Set(); let match; // 遍历所有@font-face规则 while ((match = fontFaceRegex.exec(cssText)) !== null) { const weightMatch = fontWeightRegex.exec(match[1]); if (!weightMatch) continue; let weightVal = weightMatch[1].toLowerCase(); // 将关键字转换为对应的标准数值 switch(weightVal) { case 'normal': weightVal = '400'; break; case 'bold': weightVal = '700'; break; case 'bolder': weightVal = '900'; break; case 'lighter': weightVal = '100'; break; } // 验证数值有效性(100-900,100的倍数) const numWeight = parseInt(weightVal, 10); if (!isNaN(numWeight) && numWeight >= 100 && numWeight <= 900 && numWeight % 100 === 0) { weights.add(numWeight); } } // 转换为排序后的数组返回 return Array.from(weights).sort((a, b) => a - b); } // 绑定文件上传事件示例 document.getElementById('font-css-upload').addEventListener('change', (e) => { const file = e.target.files[0]; if (!file || !file.type.includes('text/css')) { alert('请选择有效的CSS文件'); return; } const reader = new FileReader(); reader.onload = (event) => { const cssContent = event.target.result; const availableWeights = extractFontWeights(cssContent); console.log('可用font-weight列表:', availableWeights); // 此处将availableWeights渲染到编辑器下拉列表 }; reader.readAsText(file); });
方案二:CSSOM API解析(精准可靠)
利用浏览器原生的CSS解析引擎,能处理复杂CSS(如注释、不规则空格、嵌套规则),结果更准确:
async function extractFontWeightsWithCSSOM(cssText) { const weights = new Set(); const styleSheet = new CSSStyleSheet(); try { // 异步加载CSS内容到样式表 await styleSheet.replace(cssText); } catch (err) { console.error('CSS解析失败:', err); return []; } // 遍历所有规则,筛选@font-face规则 for (const rule of styleSheet.cssRules) { if (rule.type !== CSSRule.FONT_FACE_RULE) continue; const fontWeight = rule.style.fontWeight; if (!fontWeight) continue; let weightVal = fontWeight.toLowerCase(); // 关键字转数值 switch(weightVal) { case 'normal': weightVal = '400'; break; case 'bold': weightVal = '700'; break; case 'bolder': weightVal = '900'; break; case 'lighter': weightVal = '100'; break; } const numWeight = parseInt(weightVal, 10); if (!isNaN(numWeight) && numWeight >= 100 && numWeight <= 900 && numWeight % 100 === 0) { weights.add(numWeight); } } return Array.from(weights).sort((a, b) => a - b); } // 文件上传处理示例 document.getElementById('font-css-upload').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file || !file.type.includes('text/css')) { alert('请选择有效的CSS文件'); return; } const cssContent = await file.text(); const availableWeights = await extractFontWeightsWithCSSOM(cssContent); console.log('可用font-weight列表:', availableWeights); // 渲染到编辑器下拉列表 });
方案对比与注意事项
- 正则方案:轻量、同步、兼容性好,但无法处理极端复杂的CSS语法(如嵌套注释、无效规则)。
- CSSOM方案:精准、能处理所有合法CSS,但需要异步操作,在Node.js环境需额外引入
cssom库。 - 统一处理:将
normal/bold等关键字转换为标准数值,确保下拉列表展示格式一致。 - 有效性校验:只保留100-900之间100倍数的有效值,过滤非法值。
- 去重排序:用
Set自动去重,最后排序保证列表有序。
内容的提问来源于stack exchange,提问作者Arif
相关产品推荐
相关产品推荐

