【问题标题】:Why can't radio buttons be "readonly"?为什么单选按钮不能是“只读”的?
【发布时间】:2025-11-30 13:15:02
【问题描述】:

我想显示一个单选按钮,提交它的值,但根据具体情况,它是否不可编辑。 Disabled 不起作用,因为它不提交值(或者提交了?),并且它使单选按钮变灰。只读是我真正想要的,但由于某种神秘的原因它不起作用。

我是否需要使用一些奇怪的技巧才能使只读模式按预期工作?我应该只用 JavaScript 来做吗?

顺便说一句,有谁知道为什么只读在单选按钮中不起作用,而在其他输入标签中起作用?这是 HTML 规范中那些难以理解的遗漏之一吗?

【问题讨论】:

  • “这是 HTML 规范中那些难以理解的遗漏之一吗?”从用户的角度考虑。为什么要显示他们无法点击的按钮?
  • 为什么要显示一个他们不能点击的按钮?因为我希望他们知道按钮在那里,但我不希望他们现在能够单击它。但也许以后。毕竟,这是一种动态形式。为什么单选按钮与任何其他输入字段有任何不同?
  • 这里是规范:w3.org/TR/html401/interact/forms.html#h-17.12.2 "以下元素支持只读属性:INPUT 和 TEXTAREA。"这显然是错误的。但是,回到这里,我们看到了更准确的摘要:w3.org/TR/WD-forms-970402#readonly“READONLY 适用于 TEXT 或 PASSWORD 类型的 INPUT 元素以及 TEXTAREA 元素。”看起来这已经在记录和规格的差距之间滑动了。
  • 更加好奇。根据这个古老的文档“例如,在复选框中,您可以打开或关闭它们(从而设置 CHECKED 状态),但您不会更改字段的值。” (htmlcodetutorial.com/forms/_INPUT_DISABLED.html)这是真的吗?即使用户显然可以更改它,在复选框/单选上设置 READONLY 是否会锁定该值?
  • 查看我的帖子 [这里][1] 为问题 [1] 提供了一个干净简单的解决方案:*.com/a/15513256/1861389

标签: html radio-button readonly


【解决方案1】:

只有在有其他选项时,单选按钮才需要是只读的。如果您没有任何其他选项,则不能取消选中已选中的单选按钮。如果您有其他选项,您可以通过禁用其他选项来阻止用户更改值:

<input type="radio" name="foo" value="Y" checked>
<input type="radio" name="foo" value="N" disabled>

小提琴:http://jsfiddle.net/qqVGu/

【讨论】:

  • 你的第一个解决方案的问题是,如果我想通过javascript启用单选按钮,我突然有两个同名的字段,所以我必须清理其中一个。或者真正使用隐藏的,并让单选按钮设置隐藏字段的值。以太方式,它只是比我想要的单选按钮更麻烦。您的第二个解决方案,虽然我不怀疑它有效,但听起来像一个非常丑陋的黑客。所以我想javascript解决方案是唯一符合我标准的解决方案。我会同意的。
  • 请解决方案1!这是唯一一个可以正常访问的。如果您需要编写脚本,只需多行一行即可将隐藏字段的启用设置为与无线电启用的相反。
  • 我刚刚注意到解决方案 2 和 3 在 Jonathan 的回答中互换了位置,所以现在 cmets 似乎没有多大意义。
  • 想要注意 Javascript 解决方案不起作用,它只是取消选中按钮。我想它需要onclick="return false" 以防止更改。
  • 当我设置收音机“禁用”时,我添加“style=cursor:default”来删除“禁用光标”。
【解决方案2】:

我通过仅禁用未选中的单选按钮在单选按钮上伪造了只读。它可以防止用户选择不同的值,并且选中的值将始终在提交时发布。

使用jQuery进行只读:

$(':radio:not(:checked)').attr('disabled', true);

这种方法也适用于使选择列表只读,但您需要禁用每个未选择的选项。

【讨论】:

  • 感谢@Megan,这是一个很好的解决方案
  • 对此的一种变体,允许您使用 readonly 属性,正如 OP 所期望的那样:$(':radio[readonly]:not(:checked)').attr('disabled', true);
  • 在下面的解决方案中,这个解决方案提供了最干净的代码,并且与 Jquery 验证器配合得很好,因为我不需要启用/禁用字段,或者处理取消绑定点击事件并在提交时重新绑定它们表格。
  • 工作准确。谢谢
  • 聪明!使用 .not(..),如果您已经有一组选定的输入字段: var myRadios = $('#specific-radios'); myRadios.not(':checked').prop('disabled',true); api.jquery.com/not
【解决方案3】:

这是你可以使用的技巧。

<input type="radio" name="name" onclick="this.checked = false;" />

【讨论】:

  • 正是我的想法,尽管你最好澄清它应该是 onClick="this.checked = &lt;%=value%&gt;" 的某种类型:)
  • 很高兴知道。 checked 可以有 true 或 false 值。
  • 只是一个警告,对于我们这些使用默认未打开的 javascript 浏览的人来说,这将不起作用。
  • 对我来说不是问题。我们已经使用了大量的 jQuery 和 Ajax。
  • 值得注意的是,您只需执行 onclick="return false;" 即可保持组的值相同
【解决方案4】:

我有一个冗长的表单(250 多个字段),可以发布到数据库。这是一个在线就业申请。当管理员查看已提交的应用程序时,表单中会填充来自 db 的数据。输入文本和文本区域被他们提交的文本替换,但单选框和复选框对于保留为表单元素很有用。禁用它们会使它们更难阅读。将 .checked 属性设置为 false onclick 将不起作用,因为它们可能已被填写应用程序的用户选中。总之……

onclick="return false;"

事实上,它就像“禁用”收音机和复选框的魅力。

【讨论】:

    【解决方案5】:

    最好的解决方案是设置选中或未选中状态(来自客户端或服务器),并且在执行以下操作后不让用户更改它(即使其只读):

    <input type="radio" name="name" onclick="javascript: return false;" />
    

    【讨论】:

    • 不!在这种情况下,用户可以在浏览器中编辑 html,将需要的选项标记为选中并发布表单。
    • 他们可以很容易地删除“只读”属性,如果有的话。或者只是用他们的数据伪造整个请求。服务器端验证超出了这个问题的范围。
    【解决方案6】:

    我想出了一种大量使用 javascript 的方法来实现复选框和单选按钮的只读状态。它针对当前版本的 Firefox、Opera、Safari、Google Chrome 以及当前和以前版本的 IE(低至 IE7)进行了测试。

    为什么不简单地使用您要求的 disabled 属性?打印页面时,禁用的输入元素以灰色显示。实施此功能的客户希望所有元素都呈现相同的颜色。

    我不确定是否可以在此处发布源代码,因为我是在为一家公司工作时开发的,但我肯定可以分享这些概念。

    使用 onmousedown 事件,您可以在点击操作改变它之前读取选择状态。因此,您存储此信息,然后使用 onclick 事件恢复这些状态。

    <input id="r1" type="radio" name="group1" value="r1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
    <input id="r2" type="radio" name="group1" value="r2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
    <input id="r3" type="radio" name="group1" value="r3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 3</input>
    
    <input id="c1" type="checkbox" name="group2" value="c1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
    <input id="c2" type="checkbox" name="group2" value="c2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
    <input id="c3" type="checkbox" name="group2" value="c3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 3</input>
    

    这部分的 javascript 部分会像这样工作(同样只是概念):

    var selectionStore = new Object();  // keep the currently selected items' ids in a store
    
    function storeSelectedRadiosForThisGroup(elementName) {
        // get all the elements for this group
        var radioOrSelectGroup = document.getElementsByName(elementName);
    
        // iterate over the group to find the selected values and store the selected ids in the selectionStore
        // ((radioOrSelectGroup[i].checked == true) tells you that)
        // remember checkbox groups can have multiple checked items, so you you might need an array for the ids
        ...
    }
    
    function setSelectedStateForEachElementOfThisGroup(elementName) {
        // iterate over the group and set the elements checked property to true/false, depending on whether their id is in the selectionStore
        ...
    
        // make sure you return false here
        return false;
    }
    

    您现在可以通过更改输入元素的 onclick 和 onmousedown 属性来启用/禁用单选按钮/复选框。

    【讨论】:

      【解决方案7】:

      对于未选中的单选按钮,将它们标记为禁用。这可以防止他们响应用户输入并清除选中的单选按钮。例如:

      <input type="radio" name="var" checked="yes" value="Yes"></input>
      <input type="radio" name="var" disabled="yes" value="No"></input>
      

      【讨论】:

      • checked="yes"?那是什么规格?要么使用checked="checked",要么只使用不带值的checked 属性。 disabled 也一样。
      【解决方案8】:

      JavaScript 方式 - 这对我有用。

      <script>
      $(document).ready(function() {
         $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); });
      });
      </script>
      

      原因:

      1. $('#YourTableId').find('*') -> 这将返回所有标签。

      2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); 遍历在此捕获的所有对象并禁用输入标签。

      分析(调试):

      1. form:radiobutton 在内部被视为“输入”标签。

      2. 和上面的function()一样,如果你尝试打印document.write(this.tagName);

      3. 只要在标签中找到单选按钮,它就会返回一个输入标签。

      因此,通过将 * 替换为输入,上述代码行可以针对单选按钮标签进行更优化: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });

      【讨论】:

        【解决方案9】:

        一个相当简单的选择是创建一个在表单的“onsubmit”事件上调用的 javascript 函数,以启用单选按钮,以便它的值与表单的其余部分一起发布。
        它似乎不是 HTML 规范的遗漏,而是一种设计选择(逻辑上的选择,恕我直言),单选按钮不能是只读的,因为按钮不能是只读的,如果你不想使用它,那么禁用它。

        【讨论】:

          【解决方案10】:

          我发现使用onclick='this.checked = false;' 在一定程度上起作用。不会选择单击的单选按钮。但是,如果有一个单选按钮已经被选中(例如,默认值),则该单选按钮将变为未选中状态。

          <!-- didn't completely work -->
          <input type="radio" name="r1" id="r1" value="N" checked="checked" onclick='this.checked = false;'>N</input>
          <input type="radio" name="r1" id="r1" value="Y" onclick='this.checked = false;'>Y</input>
          

          对于这种情况,保留默认值并禁用其他单选按钮会保留已选择的单选按钮并防止它被取消选择。

          <!-- preserves pre-selected value -->
          <input type="radio" name="r1" id="r1" value="N" checked="checked">N</input>
          <input type="radio" name="r1" id="r1" value="Y" disabled>Y</input>
          

          此解决方案不是防止更改默认值的最优雅方法,但无论是否启用 javascript,它都可以工作。

          【讨论】:

            【解决方案11】:

            试试属性disabled,但我认为你不会得到单选按钮的值。 或者设置图片,比如:

            <img src="itischecked.gif" alt="[x]" />radio button option
            

            最好的问候。

            【讨论】:

            • 哦,我的 html 代码被剥离了:img src="itIsChecked.gif" alt="[x]" OptionChecked
            【解决方案12】:

            我正在使用 JS plugin 设置复选框/单选输入元素的样式,并使用以下 jQuery 建立“只读状态”,在该状态下仍发布基础值但用户无法访问输入元素,即我相信我们将使用只读输入属性的预期原因......

            if ($(node).prop('readonly')) {
                $(node).parent('div').addClass('disabled'); // just styling, appears greyed out
                $(node).on('click', function (e) {
                    e.preventDefault();
                });
            }
            

            【讨论】:

              【解决方案13】:

              这是我针对 Sencha ExtJS 7.2+ 的解决方案(覆盖)(单个覆盖中的复选框和单选)

              
              Ext.define('MyApp.override.field.Checkbox', {
                  override: 'Ext.field.Checkbox',
              
                  /**
                   * OVERRIDE: to allow updateReadOnly to work propperly
                   * @param {boolean} newValue
                   *
                   * To ensure the disabled state stays active if the field is still readOnly
                   * we re - set the disabled state
                   */
                  updateDisabled(newValue) {
                      this.callParent(arguments);
              
                      if (!newValue && this.getReadOnly()) {
                          this.inputElement.dom.disabled = true;
                      }
                  },
              
                  /**
                   * OVERRIDE: readonly for radiogroups and checkboxgroup do not work as other fields
                   *     https://*.com/questions/1953017/why-cant-radio-buttons-be-readonly
                   *
                   * @param {boolean} newValue
                   *
                   *  - use disabled on the field
                   */
                  updateReadOnly(value) {
                      this.callParent(arguments);
              
                      if (!this.getDisabled()) {
                          this.inputElement.dom.disabled = value;
                      }
                  }
              });
              

              【讨论】:

                【解决方案14】:

                如何在 JS 中捕获“On_click()”事件并像这里一样检查它?:

                http://www.dynamicdrive.com/forums/showthread.php?t=33043

                【讨论】:

                  最近更新 更多