如何用jQuery高效修改CSS font-family值及自定义CSS字体变量
实现方案
jQuery没有内置专门用于过滤font-family指定取值的API,你可以自己封装通用的过滤函数,结合DOM操作实现需求,比单独写复杂正则replace更易维护,适配性也更强。
核心过滤函数
首先封装通用的字体过滤方法,默认不区分大小写匹配,同时兼容带引号的多词字体族(比如"Segoe UI"):
// 定义你需要删除的字体黑名单 const forbiddenFonts = new Set(['arial', 'verdana', 'open sans'].map(f => f.toLowerCase())); /** * 过滤font-family字符串,删除黑名单内的字体 * @param {string} fontStr 原始font-family取值 * @returns {string} 过滤后的font-family取值 */ function filterFontFamily(fontStr) { // 拆分字体项,自动处理带引号的字体名称 const fontItems = fontStr.match(/(?:[^,"']+|"[^"]*"|'[^']*')+/g) || []; const filteredItems = fontItems.filter(item => { // 去除引号和前后空白后转小写匹配 const cleanName = item.trim().replace(/^["']|["']$/g, '').toLowerCase(); return !forbiddenFonts.has(cleanName); }); return filteredItems.join(', ').trim(); }
上面的函数处理你给出的示例时,输入Arial, Verdana, "Segoe UI", sans-serif会直接返回"Segoe UI", sans-serif,符合需求。
1. 处理普通font-family属性
你可以选择两种实现方式,根据页面规模选择即可:
方式1:遍历所有DOM元素修改行内样式(适配性最强)
$('*').each(function() { const originalFont = $(this).css('font-family'); if (!originalFont) return; const newFont = filterFontFamily(originalFont); if (newFont !== originalFont) { $(this).css('font-family', newFont); } });
方式2:直接修改样式表规则(大页面性能更高)
如果页面元素很多,直接遍历样式表修改规则比遍历所有DOM性能更好:
Array.from(document.styleSheets).forEach(sheet => { try { Array.from(sheet.cssRules || []).forEach(rule => { if (rule.style?.fontFamily) { const newFont = filterFontFamily(rule.style.fontFamily); if (newFont !== rule.style.fontFamily) { rule.style.fontFamily = newFont; } } }); } catch (e) { // 跨域样式表没有访问权限,直接跳过即可 } });
2. 处理CSS自定义字体变量
针对--ff-sans、--ff-serif这类自定义变量,分全局变量和局部变量两种场景处理:
处理根节点全局自定义变量
const root = document.documentElement; const rootStyle = root.style; // 你可以根据需要扩展需要匹配的字体变量名 const fontVarNames = ['--ff-sans', '--ff-serif', '--ff-mono', '--font-family-base']; fontVarNames.forEach(varName => { // 优先读取行内定义,不存在则读取计算样式覆盖外部样式表定义的变量 const originalVal = rootStyle.getPropertyValue(varName) || getComputedStyle(root).getPropertyValue(varName); if (!originalVal.trim()) return; const newVal = filterFontFamily(originalVal); if (newVal !== originalVal.trim()) { rootStyle.setProperty(varName, newVal); } });
处理元素局部自定义变量
如果需要修改非根节点上定义的局部字体变量,可以在之前遍历DOM的each回调中追加逻辑:
$('*').each(function() { // 原有处理font-family的逻辑保持不变 const originalFont = $(this).css('font-family'); if (originalFont) { const newFont = filterFontFamily(originalFont); if (newFont !== originalFont) $(this).css('font-family', newFont); } // 追加处理局部字体变量的逻辑 const style = this.style; for (let i = 0; i < style.length; i++) { const propName = style[i]; // 匹配所有以--ff-或者--font开头的自定义变量 if (propName.startsWith('--ff-') || propName.startsWith('--font')) { const originalVal = style.getPropertyValue(propName).trim(); const newVal = filterFontFamily(originalVal); if (newVal !== originalVal) { style.setProperty(propName, newVal); } } } });
注意事项
- 如果页面是动态渲染的,你可以监听
DOMNodeInserted事件或者用MutationObserver监听DOM变动,对新增的元素自动执行过滤逻辑。 - 写入行内的样式优先级高于外部样式表,不需要担心原有规则覆盖你的修改。
内容的提问来源于stack exchange,提问作者user17221954
相关产品推荐
相关产品推荐

