
本文介绍如何用纯 javascript 实现字体大小的渐进式调节:点击“-a”最多减两次至 0.5em,点击“a+”最多增两次至 1.5em,中间默认为 1em,并支持重置,避免一次性赋值导致的不可累积问题。
本文介绍如何用纯 javascript 实现字体大小的渐进式调节:点击“-a”最多减两次至 0.5em,点击“a+”最多增两次至 1.5em,中间默认为 1em,并支持重置,避免一次性赋值导致的不可累积问题。
要实现字体大小的可累积、有边界限制的动态调节(如 ±25% 每次,上限 1.5em、下限 0.5em),关键在于:不直接覆盖字体值,而是基于当前尺寸做相对增减,并实时校验边界。原始代码中 changeSizeByBtn(0.75) 是绝对赋值,导致多次点击无效;而改进方案需将按钮语义从“设为某值”改为“调整±Δ”,再结合当前样式计算新值。
✅ 正确实现步骤
-
初始化容器字体大小(推荐内联设置,确保首次读取可靠):
<div id="container" style="font-size: 1em;"> <li> <p><strong>更新按钮逻辑</strong>:传递增量而非目标值 </p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java"><img src="https://img.php.cn/upload/skill/000/000/081/178955835420587.jpg" alt="Alibabacloud Sdk Client Initialization For Java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="overflowclass">Alibabacloud Sdk Client Initialization For Java</a> <p class="overflowclass">在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。</p> </div> <a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <pre class="brush:php;toolbar:false;"><button type="button" onclick="changeSizeByBtn(-0.25)">-A</button> <button type="button" onclick="changeSizeByBtn(0)">A</button> <button type="button" onclick="changeSizeByBtn(0.25)">A+</button>
-
核心 JS 函数(带健壮性处理):
const cont = document.getElementById("container"); function changeSizeByBtn(delta) { // 重置逻辑:delta === 0 → 恢复基准 1em if (delta === 0) { cont.style.fontSize = "1em"; return; } // 安全读取当前 font-size(兼容未设置时的 fallback) let currentSize = 1; const computedStyle = getComputedStyle(cont); const fontSizeStr = computedStyle.fontSize || cont.style.fontSize; const match = fontSizeStr.match(/(\d+(\.\d+)?)em/); if (match && match[1]) { currentSize = parseFloat(match[1]); } // 计算新尺寸并约束范围 [0.5, 1.5] const newSize = Math.max(0.5, Math.min(1.5, currentSize + delta)); cont.style.fontSize = `${newSize}em`; } -
避免
style.fontSize为空时解析失败:使用getComputedStyle()作为兜底,确保即使未显式设置style.fontSize也能读取真实渲染值; -
正则匹配更鲁棒:
/(\d+(\.\d+)?)em/比简单match(/\d+(?:\.\d+)?/)更精准,防止误匹配其他数字; -
边界使用
Math.max/min:比if判断更简洁且无分支遗漏风险; -
CSS 继承保障:确保
#container内所有文本元素(h1,p等)使用em单位定义字体,才能随容器缩放(示例中已满足)。 - 初始:
1em→ 点击-A→0.75em→ 再点-A→0.5em(锁定,继续点击无效) - 初始:
1em→ 点击A+→1.25em→ 再点A+→1.5em(锁定) - 任意状态点击
A→ 立即回归1em
⚠️ 注意事项
? 效果验证
该方案轻量、无依赖、兼容性强,适用于无障碍字体调节、阅读模式切换等场景,是响应式排版中实用的渐进增强实践。










