
本文详解为何直接通过 style.fontVariationSettings 切换 'FILL' 值在 if-else 中失效,并提供两种可靠解决方案:修正字符串匹配方式与推荐的 CSS 类名切换法。
本文详解为何直接通过 `style.fontvariationsettings` 切换 `'fill'` 值在 if-else 中失效,并提供两种可靠解决方案:修正字符串匹配方式与推荐的 css 类名切换法。
在使用 Google 的 Material Symbols 图标(如 )时,常需通过 font-variation-settings 控制其填充状态('FILL' 0 表示线性图标,'FILL' 10 表示实心图标)。许多开发者尝试用 JavaScript 监听点击事件并动态修改 element.style.fontVariationSettings,却发现加入 if...else 判断后逻辑不再生效——看似正确的条件始终不满足,图标状态无法切换。
根本原因在于:浏览器对 style.fontVariationSettings 的读取值会自动标准化(canonicalize)为双引号格式,而 CSS 中声明使用的是单引号。例如,即使你在 CSS 中写的是 'FILL' 0,通过 element.style.fontVariationSettings 读取到的值实际是 "FILL" 0(注意双引号)。因此,原始代码中:
if (star.style.fontVariationSettings === "'FILL' 0") { /* 永远为 false */ }
该条件永远为 false,因为运行时获取的是 "FILL" 0,字符串不匹配导致分支逻辑失效。
✅ 方案一:修正字符串匹配(可行但不推荐)
将比较和赋值统一改为双引号格式:
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';
}
});
⚠️ 注意:此方式依赖内联样式的存在。若初始 font-variation-settings 完全来自 CSS(未通过 style 属性设置),则 star.style.fontVariationSettings 可能为空字符串,首次点击仍无法触发预期行为。
✅✅ 方案二:使用 classList.toggle() + CSS 类(强烈推荐)
这是更健壮、可维护、符合 Web 标准的最佳实践。它将样式逻辑完全交由 CSS 管理,JavaScript 仅负责状态切换:
HTML:
<button id="star" class="material-symbols-outlined star">star</button>
CSS(styles.css):
.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;
}
JavaScript(myscript.js):
const star = document.getElementById('star');
star.addEventListener('click', () => {
star.classList.toggle('fill10');
});
该方案优势显著:
- ✅ 解耦清晰:样式定义在 CSS,行为逻辑在 JS,便于复用与主题定制;
- ✅ 无字符串匹配风险:避免因引号、空格、顺序等细微差异导致的运行时错误;
- ✅ 支持 CSS 过渡动画:可在 .star 或 .star.fill10 中添加 transition: font-variation-settings 0.2s ease 实现平滑填充变化;
- ✅ 天然支持 SSR/框架集成:类名操作是现代前端通用范式。
? 额外提示:
- 确保已正确引入 Material Symbols 字体(通过 );
- 若需持久化用户偏好(如收藏状态),可在 toggle 后同步更新 localStorage 并初始化类名;
- 对于多个图标,可封装为通用函数:toggleFill(el) { el.classList.toggle('fill10'); }。
综上,放弃直接操作 style.fontVariationSettings 的字符串判断,转而采用语义化类名控制图标状态,是解决 Fill 切换失效问题的专业、可持续方案。










