有没有一种方法可以同时禁用一堆表单元素?

16

我想根据一些条件禁用 HTML 表单元素的某个部分。这似乎是实现这一目标的最佳方法:

<fieldset disabled>
    <input value="one" />
    <input value="two" />
</fieldset>

现在,这两个输入已被禁用。但是在IE8上似乎完全出现了问题。这些输入框看起来被禁用了,但我仍然可以在其中输入内容。

演示(不像 JsFiddle 在 IE8 上真正起作用)

是否有跨浏览器的解决方案来解决这个问题,而不需要向每个表单元素添加 disabled (这将使我的脚本更加复杂)。我可能可以使用 jQuery 选择 <fieldset>,然后通过所有表单元素进行循环并禁用它们 - 但实际上我正在使用 Knockout 绑定来设置 disabled 属性,因此没有地方添加这样的代码。我的最后一招是使用自定义 Knockout 绑定来禁用所有子级,但是这太烦人了。


1
你可以使用覆盖层来防止点击输入框,但这并不能阻止通过tab键访问它们,所以你仍然需要使用tabindex属性。你可以绑定一个事件来防止keydown事件的发生,甚至是focus事件。 - Kevin B
是的,我不是非常喜欢那个解决方案。此外,将其集成到Knockout模板中仍然很麻烦。我宁愿逐个禁用每个元素。 - Mike Christensen
@MikeChristensen:在IE8中,fieldset并不是borked,只是支持不完全。fieldset是HTML5的一个补充,而IE8仅支持极少量的HTML5表单元素。请参见http://html5test.com results for IE8fieldset在IE8中只有部分支持。正如结果所示,element attributes不被支持。因此,您可能需要想出一种替代方案。正如建议的那样,覆盖层可能是其中之一。虽然可能会有一个polyfill可以在IE8中使用fieldset,但我不能百分之百确定。 - Nope
@MikeChristensen:如果您必须支持IE8,则另一种解决方案是根本不使用任何HTML5元素。我并不是在聪明,我只是建议它作为一个选项。此外,我不得不承认,这很奇怪,因为根据我在先前评论中链接的HTML5测试结果,disabled 属性应该在IE8中得到支持。当在运行HTML5测试的IE8上转到http://html5test.com/时也会显示相同的结果。确实很奇怪。 - Nope
5个回答

11

好的,我已经想出了一个针对 Knockout.js 的具体实现,希望能帮助其他一些处于同样情境中的人。这个解决方案可能需要花费一点努力才能适应其他解决方案和平台。

首先,我创建了一个 Knockout 绑定:

ko.bindingHandlers.allowEdit = {
   init: function(element, valueAccessor)
   {
      if(!valueAccessor())
      {
         element.disabled = true;
         element.readOnly = true;

         if(element.tagName === 'FIELDSET')
         {
            $(':input', element).attr('disabled', 'disabled');
         }
      }
   }
};

请注意,如果您希望允许更改此绑定,那么还必须实现update方法。我没有这个要求。

然后您可以像这样使用绑定:

<fieldset data-bind="allowEdit: someExpression">
   <input value="One" />
   <input value="Two" />
</fieldset>

$('fieldset :input').attr('disabled', '');$('fieldset :input').removeAttr('disabled'); 看起来包括文本域和选择框。您可能不需要单独指定它们:http://jsfiddle.net/CvafW/1/ 不确定在所有浏览器中是否相同。 - Nope
@FrançoisWahl - 是的,你说得对。正在更新我的代码。 - Mike Christensen
哦,当然还有+1,因为这是一个看起来对你有用并且很可能对将来使用knockoutJS解决类似问题的用户有用的解决方案。 - Nope

4
简而言之:不行。原因是IE8的支持不足以及fieldset元素上的disabled属性。 来源

在IE7和IE8中,该属性仅禁用<legend>中的表单元素。

我很抱歉,你应该寻找自定义解决方案,例如其他用户的答案/自己的自定义绑定。

我正在查看http://html5test.com/compare/browser/ie08.html,其中指出支持disabled属性,但不支持元素属性。非常令人困惑。我会记下你提供的链接。+1 for the source. - Nope

2
使用jQuery的解决方案:
var disabledFiedset=$('fieldset[disabled]');
$('input',disabledFiedset).attr('disabled','disabled');

1
+1 因为我使用了你的部分解决方案。 - Mike Christensen

1

我能够使用模型中的可观察对象来实现类似的功能,称为editable,在我的输入中使用了data-bind="enable: editable",在IE 7、8和9中完全有效。


当然可以,但你需要在每个表单字段上都加上这个。 - Mike Christensen
是的,但它都由一个可观察对象控制。 - segFault

0
将id赋给你的fieldset标签(或者你也可以直接在jquery代码中使用标签名),并使用以下代码来使用jquery使该fieldset中的所有字段都不可用。 $("#fieldset id" 或 "fieldset").children().attr("disabled", "disabled");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接