本文详解为何直接通过 style.fontVariationSettings 配合 if-else 切换图标填充状态会失效,并提供两种稳定可靠的解决方案:修正字符串匹配方式与推荐的 CSS 类切换法。
本文详解为何直接通过 `style.fontvariationsettings` 配合 if-else 切换图标填充状态会失效,并提供两种稳定可靠的解决方案:修正字符串匹配方式与推荐的 css 类切换法。
在使用 Google 的 Material Symbols 图标(如 )时,常需通过 font-variation-settings 的 'FILL' 轴控制图标是否实心填充。许多开发者尝试用 JavaScript 监听点击事件并动态修改 element.style.fontVariationSettings,却发现加入 if-else 判断后逻辑不再生效——看似代码结构正确,但图标状态始终无法切换。
根本原因在于:
浏览器对 style.fontVariationSettings 的读取值会自动标准化(canonicalize)为双引号格式
,而你在 CSS 中写的是单引号('FILL' 0),但 JS 通过 element.style.fontVariationSettings 读取到的却是 "FILL" 0(含英文双引号)。因此,原始条件 === "'FILL' 0" 永远为 false,导致分支逻辑失效。
✅ 正确的字符串匹配写法如下(修复版内联样式方案):
⚠️ 但该方案存在明显缺陷:
依赖字符串精确匹配,易受空格、引号类型、顺序变化影响;
若 CSS 中还设置了其他 variation 轴(如 'wght' 400),style.fontVariationSettings 会返回完整字符串(如 '"FILL" 0, "wght" 400'),单纯匹配 "FILL" 0 将失败;
违反关注点分离原则,将样式逻辑耦合进 JS。
✅
强烈推荐:使用 classList.toggle() + CSS 类管理(最佳实践)
HTML 保持简洁:
CSS 定义基础态与填充态:
JavaScript 仅负责状态切换,语义清晰、健壮性强:
? 补充提示:
font-variation-settings 是实验性属性,确保目标浏览器支持(Chrome/Firefox/Edge ≥ v87,Safari ≥ v16.4);
Material Symbols 字体需正确加载(通过 );
若需持久化状态(如刷新后保留),可结合 localStorage 存储布尔值,并在页面加载时初始化类名。
综上,避免直接操作 style.fontVariationSettings 的字符串值进行条件判断;拥抱 CSS 类驱动的状态管理,既提升可维护性,又确保跨浏览器行为一致。
const star = document.getElementById('star');
star.addEventListener('click', () => {
// 注意:读取值是双引号包裹的字符串!
if (star.style.fontVariationSettings === '"FILL" 0') {
star.style.fontVariationSettings = '"FILL" 10';
} else {
star.style.fontVariationSettings = '"FILL" 0';
}
});.star {
/* 默认:空心图标 */
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
background: none;
border: none;
color: var(--check-color);
cursor: pointer;
}
/* 激活态:实心填充 */
.star.fill10 {
font-variation-settings: 'FILL' 10, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}const star = document.getElementById('star');
star.addEventListener('click', () => {
star.classList.toggle('fill10'); // 自动增删类,无需手动判断
});