PAYATHON 2026

radio input 位于 label 内时如何更新标签文本

数据阿明

结论

不要对包含 radio input 的 <label> 使用 $(label).text(newText)。调用 .text() 写入内容时,会清空标签中的所有子节点,包括内部的 <input>。

在现有 HTML 结构下,可以只找到 <label> 中的文本节点并修改其 nodeValue。这样既能更新文字,也能完整保留 radio input。

适用于当前结构的写法

假设 HTML 结构如下:

<div id="timePeriods">
  <label><input type="radio" name="timePeriod" value="3"> 3 Months</label>
  <label><input type="radio" name="timePeriod" value="6"> 6 Months</label>
  <label><input type="radio" name="timePeriod" value="9"> 9 Months</label>
  <label><input type="radio" name="timePeriod" value="12"> 12 Months</label>
</div>

可以这样更新文字:

$("input[name='timeFrame']").on("change", function () {
    var unit = $(this).val() === "months" ? "Months" : "Cycles";

    $("#timePeriods label").each(function () {
        $(this).contents().filter(function () {
            return this.nodeType === 3; // Text 节点
        }).each(function () {
            this.nodeValue = this.nodeValue.replace(
                /\b(?:Months|Cycles)\b/g,
                unit
            );
        });
    });
});

contents() 会取得 <label> 内的元素节点和文本节点,再通过 nodeType === 3 筛选出文本节点。直接修改 nodeValue 不会重新创建 <label>,也不会影响其中 radio input 的选中状态、事件或 jQuery 数据。

为什么原代码会删除 radio input

问题出在这句代码:

$(this).text(newLabel);

它并非只修改页面上显示的文字,而是用新的纯文本替换 <label> 的全部内容。替换后的效果近似于:

<label>3 Cycles</label>

原本位于 <label> 内的元素也会被清除,其中包括:

<input type="radio">

更推荐的 HTML 结构

如果能够调整 HTML,最好用单独的元素包裹需要变化的文字:

<div id="timePeriods">
  <label>
    <input type="radio" name="timePeriod" value="3">
    <span>3 Months</span>
  </label>

  <label>
    <input type="radio" name="timePeriod" value="6">
    <span>6 Months</span>
  </label>

  <label>
    <input type="radio" name="timePeriod" value="9">
    <span>9 Months</span>
  </label>

  <label>
    <input type="radio" name="timePeriod" value="12">
    <span>12 Months</span>
  </label>
</div>

这样更新代码会简单许多:

$("input[name='timeFrame']").on("change", function () {
    var unit = $(this).val() === "months" ? "Months" : "Cycles";

    $("#timePeriods label span").each(function () {
        $(this).text(function (_, text) {
            return text.replace(/\b(?:Months|Cycles)\b/g, unit);
        });
    });
});

注意事项

  • $(label).text() 可以安全读取完整文字,但当 label 内含有 input 时,不能用它直接覆盖内容。
  • 使用 Months|Cycles 同时匹配两种单位,比依赖当前的旧文本更稳妥。即使重复触发 change,替换结果也不会出错。
  • 如果 <label> 中还有说明、图标或其他文本节点,建议用 <span> 包裹可变文字,以免修改无关内容。
  • 判断条件中的 "months" 必须与 Time Frame radio 的实际 value 完全一致,包括大小写。

备注:内容仅供参考。