
事情是这样的我用 Elementor 搭一个招聘专题页里面放了几个“技能掌握度”进度条客户看完设计稿提了一句百分比后面那个“%”看着重复能不能只留数字我心想这不是小事一桩么结果翻遍了 Progress Bar 的设置面板——进度条颜色能改、数值能填、动画时长能调就是找不到一个“隐藏百分号”的开关。真正动手看前端 DOM 才发现百分比文本是 Elementor 的 JS 动态写进去的不是后台设置里的一行静态文字所以问题远没有想象中简单。这篇文章我把这次排查和解决过程完整写出来覆盖三种思路直接隐藏整个百分比、保留数字去掉百分号、以及通过 PHP 做内容输出层处理。无论你是只有 Elementor 免费版还是用了 Elementor Pro方法都适用看完照着抄就能改掉。1. 先把进度条的前端结构和渲染原理搞清楚1.1 进度条在浏览器里到底渲染成了什么动手改之前我建议你先按 F12 打开浏览器的开发者工具在页面上点到那个进度条元素看下它的真实 HTML 结构。不同 Elementor 版本的结构会有一点点差异但大体上是这个样子div classelementor-progress-wrapper roleprogressbar aria-valuemin0 aria-valuemax100 aria-valuenow85 aria-label设计能力 div classelementor-progress-bar>el.textContent Math.round(currentValue) %;所以只改后台设置、只改 HTML 静态文本都治标不治本。理解了这一点后面的方案才有意义要么用 CSS 把整个百分比藏掉要么等 Elementor 写完文本后马上把%剔除要么干脆让脚本输出的时候就不带%。提示Elementor 免费版和 Pro 版的 Progress Bar 在前端动能上没有本质区别免费版同样有这个百分比文本自动更新逻辑。因此下面的方案两种版本通用。2. 动手之前先分清你要的是哪种效果2.1 “去掉%符号”这个需求其实对应两种情况我接触到的大部分需求其实是这两种百分比数字也不想显示纯进度条就够了。常见于设计感较强的页面进度条本身的颜色和宽度足以表达含义百分比的文字反而是视觉噪音。数字要保留只是去掉后面的百分号。常见于简历页、产品卖点页、数据展示页设计师希望“80”比“80%”看起来更干净、更有数据感。这两种情况的最优解完全不同。如果你直接搜“Elementor 去掉百分比”搜出来的答案多半是display: none隐藏整个百分比元素。这个办法只适用于第一种场景放到第二种场景就会翻车——数字也没了。2.2 不同需求对应的方案选择我先把最终结论放在前面后面每个方案再展开讲需求推荐方案改动方式难度百分比整个隐藏方案A一行 CSSElementor 页面设置或 WP 自定义 CSS极低保留数字、只去掉 %方案BMutationObservertheme 的 functions.php 或 WPCode 等代码插件中想从源头改 HTML 输出方案CPHP filtertheme 的 functions.php较低但必须结合 CSS/JS 使用我说过很多次改这类由 JavaScript 驱动的组件最忌讳的就是“只改一处”。因为组件自身会在某个时机重置 DOM 内容你静态改的那一下很快就失效了。方案 B 的底层思路是监听变化、动态清理这正好规避了这个问题方案 A 是直接不显示一劳永逸方案 C 则是把问题前移到服务端输出阶段但动画场景下有被覆盖的风险。3. 三种去掉%符号的实操方案3.1 方案A只用 CSS 隐藏整个百分比元素这是最省事的方案适合你根本不想要那个数字的情况。在 WordPress 后台的“外观 → 自定义 → 额外 CSS”里粘贴.elementor-widget-progress .elementor-progress-percentage { display: none; }加.elementor-widget-progress前缀是为了避免误伤页面里其他叫.elementor-progress-percentage的元素。虽然这种类名大概率不会重复但写选择器时把上下文收窄是一个值得养成的习惯。如果你只希望某个特定页面的进度条隐藏还可以给那个页面单独加一个 body class再写.my-no-percentage-page .elementor-progress-percentage { display: none; }优点一句话不依赖 JS、不影响动画、性能开销为零。缺点也很直观数字和百分号一起消失了。如果你需要保留数字直接跳过这个方法去看方案 B。3.2 方案B用 MutationObserver 实时剔除百分号方案 B 是我的首选也是这次项目里最终落地方案。原理很简单监听.elementor-progress-percentage这个节点的文本变化一旦发现里面带了%立刻把它替换成空字符串只保留数字。3.2.1 背景知识为什么不用简单的 setInterval可能有人会想我用 jQuery 定时把文本里的%删掉不行吗可以但不好。setInterval是持续轮询即使没有文本变化也在空转而且如果轮询间隔太短会跟 Elementor 的动画更新互相打架稍微写不好就是页面卡顿。MutationObserver 不一样它是浏览器原生提供的事件机制只在 DOM 文本真正变化时才触发回调资源消耗可以忽略而且不会出现肉眼可见的中间状态。3.2.2 完整 JavaScript 代码把这段代码放到 WordPress 页脚输出或者用 WPCode、Code Snippets 之类插件加载(function () { function cleanPercentage() { var nodes document.querySelectorAll(.elementor-progress-percentage); nodes.forEach(function (node) { var clean function () { var text node.textContent || ; // 只在包含 % 时才处理避免死循环 if (text.indexOf(%) ! -1) { node.textContent text.replace(/%/g, ); } }; clean(); var observer new MutationObserver(clean); observer.observe(node, { childList: true, characterData: true, subtree: true }); }); } if (document.readyState loading) { document.addEventListener(DOMContentLoaded, cleanPercentage); } else { cleanPercentage(); } })();这段代码有几个细节我想单独说明text.indexOf(%) ! -1这个判断非常重要。因为clean函数通过node.textContent ...修改了文本内容而 MutationObserver 会再次触发clean如果没有这个判断就会形成“改文本 → 触发观察 → 再改文本”的死循环。观察的对象是文本节点层级我们用的是childList和characterData一起监听。Elementor 更新进度时通常直接改文本内容两个选项都能覆盖到。forEach配合NodeList在现代浏览器里没有问题如果你需要兼容特别老的浏览器可以换成Array.prototype.forEach.call(...)。3.2.3 代码放到哪里才不白写JS 代码不能放到 WordPress 的“额外 CSS”里那里只支持 CSS。我一般推荐两种方式第一种用代码管理插件比如 WPCode新建一个“JavaScript”类型的代码片段选择在wp_footer加载。这是最省事、也不会因为升级主题而丢失的做法。第二种手动加到当前主题的 functions.php 里通过wp_footer钩子输出add_action(wp_footer, function () { if (is_singular()) { ? script (function () { function cleanPercentage() { var nodes document.querySelectorAll(.elementor-progress-percentage); nodes.forEach(function (node) { var clean function () { var text node.textContent || ; if (text.indexOf(%) ! -1) { node.textContent text.replace(/%/g, ); } }; clean(); var observer new MutationObserver(clean); observer.observe(node, { childList: true, characterData: true, subtree: true }); }); } if (document.readyState loading) { document.addEventListener(DOMContentLoaded, cleanPercentage); } else { cleanPercentage(); } })(); /script ?php } });我通常不用is_singular()限制页面范围但因为这次只需要在一个专题页上生效所以加个限制更稳妥。如果你在小程序落地页、首页、文章页等多个地方都用进度条可以去掉这个条件判断。3.2.4 动画过程中会不会出现“85%”闪一下再变“85”这是我在实际测试中最担心的问题。Elementor 动画更新百分比数字的时机比较频繁如果浏览器先绘制了“85%”再执行我们的清理用户就会看到百分号闪烁。实测下来在 Chrome、Firefox 和 Safari 里MutationObserver 的回调属于微任务会在浏览器下一次绘制之前执行完毕。简单说Elementor 脚本把文本改成“85%”后浏览器还没来得及把这一帧画出来我们就已经把它改成了“85”所以用户那边看到的就是一个没有百分号的纯净数字。这正是这个方案比 PHP filter 更稳的原因之一。3.3 方案C从服务端输出阶段处理百分号方案 C 的思路是修改 Elementor 渲染内容时的输出结果。Elementor 提供了一个内容过滤器很多自定义小部件功能都建立在它上面。在 functions.php 里加add_filter(elementor/frontend/render_content, function ($content, $element) { if (method_exists($element, get_name) $element-get_name() progress) { $content preg_replace( /(span classelementor-progress-percentage)(\d)(%)(\/span)/, $1$2$4, $content ); } return $content; }, 10, 2);这段代码会把服务端生成的 HTML 里“85%”改成“85”从根源去掉了百分号。但我要坦白说这个方案有个明显的坑如果这个进度条开启了播放动画Elementor 的 JS 在动画更新文本时会重新拼上%服务端改完的 HTML 很快又被前端覆盖了。所以方案 C 更适合用在那些禁用了动画、或者在页面加载时就已经是最终数值的进度条上一旦动画开启它不能单独使用还是要配合方案 B 的 MutationObserver 一起。这也是我为什么把方案 B 作为首选的原因。如果你确实想用方案 C又开着动画那最终效果其实等于“PHP 改一遍JS 又改一遍”多一重保障但也多一份缓存兼容问题。我自己的实践结论是输出层改动适合给“纯静态展示型”页面用追求动效的页面不要本末倒置。4. 常见问题与避坑指南4.1 一个页面上有多个进度条会不会有的生效有的没生效按我上面写的选择器.elementor-progress-percentage它会匹配全部进度条所以多个组件会一起被处理。真正需要注意的场景是进度条被放在 Elementor 的 Tab、手风琴、弹窗或延迟加载区域里。这些组件可能在页面初始加载时并不存在等用户点击某个 Tab 或弹窗弹出时才渲染 DOM我们的querySelectorAll在DOMContentLoaded时根本找不到它们。遇到这种情况有两个简单处理办法。一是全局用一个MutationObserver监听document.body发现新增的.elementor-progress-percentage节点就绑定清理逻辑二是在 Elementor 的frontend/element_ready/progress.default钩子里初始化处理。后者略复杂但更贴合 Elementor 的机制。我写了个简化版本jQuery(window).on(elementor/frontend/init, function () { elementorFrontend.hooks.addAction(frontend/element_ready/progress.default, function ($scope) { $scope.find(.elementor-progress-percentage).each(function () { // 这里执行 clean 逻辑 }); }); });如果你对elementorFrontend.hooks不熟可以先从全局 MutationObserver 入手逻辑更直白。4.2 经典问题速查表现象原因处理方法百分号没去掉JS 没有执行或执行太早确认代码在 wp_footer 输出F12 看 Console 有没有报错百分号一闪而过观察者绑定失败或者进度条在折叠内容里改用frontend/element_ready/progress.default初始化数字也没了你用的是方案 A 的 CSS换成方案 B或调整选择器其他地方的百分号被误删选择器太宽泛加上.elementor-widget-progress限定页面有 CDN/缓存插件改了不生效前端被缓存清理缓存插件、CDN 缓存最好给资源加版本号Angular/Vue 项目里也有 Elementor这种情况比较罕见确认页面真的是由 WordPress 渲染再按上面的方法处理4.3 去掉百分号之后还想优化数字样式去掉%之后数字在整个进度条右侧可能会显得有点突兀我会顺手把它的字号、颜色再统一一下让它和进度条文字在视觉上更协调。这里给出的不是固定答案只是一套安全的默认值.elementor-widget-progress .elementor-progress-percentage { font-size: 16px; line-height: 1; margin-left: 8px; color: #333; }但要提醒一句如果进度条设置了较短的动画时长数字变化频率很高那么只改 CSS 不会影响清理逻辑放心用。4.4 我的真实感受与建议整体做下来我最大的体会是Elementor 这类可视化页面构建器很多东西在后台并不暴露开关但它没有把前端代码完全锁死CSS 类和钩子都还留着给了我们很大的操作空间。遇到这种“看得到但删不掉”的小元素与其反复刷新页面试错不如先打开开发者工具看一眼 DOM 结构再决定从哪一层动手。另外代码上线后一定要清一次缓存。我遇到过好几次明明 JS 已经写好了刷新页面还是老样子不是代码错了而是 WP 的缓存插件把旧的 HTML 和脚本一起缓存了。清完缓存再看事半功倍。至于方案选型我的原则很简单能静态就不动态能原生就不轮询。纯隐藏用 CSS保留数字去掉百分号且希望适配一切动画场景就用 MutationObserver。希望你这次改完进度条看起来干干净净。