如何使用LABEL标签的FOR属性,而INPUT标签上没有ID属性


78

以下代码中说明的问题有解决方案吗?首先,在浏览器中打开代码以直接理解问题,而不必在了解所需内容之前仔细阅读所有代码。

<html>
 <head>
  <title>Input ID creates problems</title>
  <style type="text/css">
   #prologue, #summary { margin: 5em; }
  </style>
 </head>
 <body>
  <h1>Input ID creates a bug</h1>
  <p id="prologue">
   In this example, I make a list of checkboxes representing things which could appear in a book. If you want some in your book, you check them:
  </p>
  <form>
   <ul>
    <li>
     <input type="checkbox" id="prologue" />
     <label for="prologue">prologue</label>
    </li>
    <li>
     <input type="checkbox" id="chapter" />
     <label for="chapter">chapter</label>
    </li>
    <li>
     <input type="checkbox" id="summary" />
     <label for="summary">summary</label>
    </li>
    <li>
     <input type="checkbox" id="etc" />
     <label for="etc">etc</label>
     <label>
    </li>
   </ul>
  </form>
  <p id="summary">
   For each checkbox, I want to assign an ID so that clicking a label checks the corresponding checkbox. The problems occur when other elements in the page already use those IDs. In this case, a CSS declaration was made to add margins to the two paragraphs which IDs are "prologue" and "summary", but because of the IDs given to the checkboxes, the checkboxes named "prologue" and "summary" are also affected by this declaration. The following links simply call a javascript function which writes out the element whose id is <a href="javascript:alert(document.getElementById('prologue'));">prologue</a> and <a href="javascript:alert(document.getElementById('summary'));">summary</a>, respectively. In the first case (prologue), the script writes out [object HTMLParagraphElement], because the first element found with id "prologue" is a paragraph. But in the second case (summary), the script writes out [object HTMLInputElement] because the first element found with id "summary" is an input. In the case of another script, the consequences of this mix up could have been much more dramatic. Now try clicking on the label prologue in the list above. It does not check the checkbox as clicking on any other label. This is because it finds the paragraph whose ID is also "prologue" and tries to check that instead. By the way, if there were another checkbox whose id was "prologue", then clicking on the label would check the one which appears first in the code.
  </p>
  <p>
   An easy fix for this would be to chose other IDs for the checkboxes, but this doesn't apply if these IDs are given dynamically, by a php script for example.
   Another easy fix for this would be to write labels like this:
   <pre>
    &lt;label&gt;&lt;input type="checkbox" /&gt;prologue&lt;/label&gt;
   </pre>
   and not need to give an ID to the checkboxes. But this only works if the label and checkbox are next to each other.
  </p>
  <p>
   Well, that's the problem. I guess the ideal solution would be to link a label to a checkboxe using another mechanism (not using ID). I think the perfect way to do this would be to match a label to the input element whose NAME (not ID) is the same as the label's FOR attribute. What do you think?
  </p>
 </body>
</html>

2
除了没有明确的问题外,这是stackoverflow.com/questions/8537621/…的副本。
Mark E. Haase

Answers:


15

我认为最好的办法是重命名所有复选框,例如在其ID上添加一些前缀。 input

   <ul>
    <li>
     <input type="checkbox" id="input_prologue" />
     <label for="input_prologue">prologue</label>
    </li>
    <li>
     <input type="checkbox" id="input_chapter" />
     <label for="input_chapter">chapter</label>
    </li>
    <li>
     <input type="checkbox" id="input_summary" />
     <label for="input_summary">summary</label>
    </li>
    <li>
     <input type="checkbox" id="input_etc" />
     <label for="input_etc">etc</label>
    </li>
   </ul>

这样,您将与页面上的其他ID没有任何冲突,并且单击标签将切换复选框,而无需任何特殊的javascript功能。


139

它已经在这里解决:https : //stackoverflow.com/a/8537641 像这样做

<label><input type="checkbox">Some text</label>

10
仅当标签和复选框彼此相邻时才有效。
肖恩

11
@Shawn原始帖子就是这种情况。
Igor Zevaka 2014年

我唯一推荐的是将文本放在输入标签之前。否则,完美!
斯坦

5
问题是您必须对其进行样式设置。CSS中没有父选择器。
Maciej Krawczyk

1
在某些布局中可能无法实现,但是如果没有JS,就无法链接标签和输入。这是WC3批准的解决方案,不使用链接的ID。而且,如果您确实遇到样式或标记问题,请使用JS。
佩里

7

编辑:回想起来,我的解决方案远非理想。我建议您改为使用此答案中所示的“隐式标签关联”:stackoverflow.com/a/8537641/884734

我提出的低于理想的解决方案如下:

只需使用一些JavaScript即可轻松解决此问题。只需将以下代码放在页面的js文件之一中,即可为<label>标签提供以下行为:

单击标签时:

如果页面上的某个元素具有与id标签for属性匹配的元素,请还原为默认功能并集中输入。

如果使用未找到匹配id,寻找的兄弟姐妹label有一个class匹配labelfor属性,并将重点。

这意味着您可以像这样布置表格:

<form>
    <label for="login-validation-form-email">Email Address:</label>
    <input type="text" class="login-validation-form-email" />
</form>

the,实际代码:

$(function(){
    $('body').on('click', 'label', function(e){
        var labelFor = $( this ).attr('for');
        if( !document.getElementById(labelFor) ){
            e.preventDefault(); e.stopPropagation();
            var input = $( this ).siblings('.'+labelFor);
            if( input )
                input[0].focus();
        }
    })
});

注意:根据W3C规范验证您的网站时,这可能会导致问题,因为该<label> for属性在页面上始终具有一个具有匹配ID的相应元素。

希望这可以帮助!


感谢谁投票支持。回想起来,我的解决方案远非理想。我建议您改用此答案中所示的“隐式标签关联”:stackoverflow.com/a/8537641/884734
Eric Seastrand 2016年

1
这不仅会导致W3C符合性验证器出现问题,而且也不适用于辅助技术,例如屏幕阅读器。正如您在评论中所写,它们需要隐式标签关联。
Volker E.

3

简而言之,一个ID仅应在一个页面上使用一次,因此,它们不会为一个不应该存在的单个页面上的多个ID设计一个变通方法。

要回答其余问题:不,ID属性是标签的“ for”属性唯一要看的东西。您始终可以使用JavaScript onclick事件来按名称获取输入并进行更改,尽管当您仅能解决ID问题时,这样做似乎过于复杂,这会更加有意义。


+1:用一块石头击中两个问题。一点没有意义的FYI:for属性的数据类型为IDREF,该数据类型查找为ID类型的值,该值必须唯一。这些是XML Schema可用的旧数据类型,所以我想这意味着它们是SGML的常驻数据类型。

11
动态创建输入的ID时会发生此问题。当我为页面上的其他元素选择ID时,我不知道它们将是什么,因此无法确保它们不会重复。正如您所说,javascript解决方案过于复杂(有些人没有javascript)。
肖恩

1
生成ID的GUID。
Triynko '16

1

也许简单直接的解决方案是使用uniqueid()php或其他编程语言替代功能。


0

与接受的答案不同,我同意FantomX1提出的解决方案,为每个复选框生成一个随机ID,并将该ID用于与该复选框关联的标签。但是我会使用uuid生成随机ID(请参阅在JavaScript中创建GUID / UUID?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.