下面的代码中是否有解决问题的方法?首先在浏览器中打开代码,直到达到目的,在知道您要查找的内容之前不必查看所有代码。
<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>
<label><input type="checkbox" />prologue</label>
</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>
答案 0 :(得分:120)
这里已经解决了: https://stackoverflow.com/a/8537641 就像这样做
<label><input type="checkbox">Some text</label>
答案 1 :(得分:14)
在我看来,最好的办法是重命名所有复选框,方法是在其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函数。
答案 2 :(得分:6)
编辑:回想起来,我的解决方案远非理想。我建议你改为使用“隐式标签关联”,如下面的答案所示:stackoverflow.com/a/8537641/884734
我提议的,不太理想的解决方案如下:
这个问题可以通过一点点javascript轻松解决。只需将以下代码放入页面的一个js文件中,即可为<label>
标记提供以下行为:
点击标签时:
如果页面上有一个元素id
与标签的for
属性相匹配,请恢复默认功能并关注该输入。
如果未找到使用id
的匹配项,请查找label
的兄弟,其中class
与label
的{{1}}属性相匹配,并且关注它。
这意味着您可以像这样布置表单:
for
唉,实际代码:
<form>
<label for="login-validation-form-email">Email Address:</label>
<input type="text" class="login-validation-form-email" />
</form>
注意:根据W3C规范验证您的网站时,这可能会导致问题,因为$(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();
}
})
});
<label>
属性应始终在页面上具有匹配ID的相应元素。
希望这有帮助!
答案 3 :(得分:3)
简单地说,一个ID只能在页面上使用一次,所以不会在一个页面上为多个ID设计一个不应该存在的解决方法。
回答问题的其余部分:不,ID属性是标签'for'属性的唯一内容。您总是可以使用JavaScript onclick事件来按名称获取输入并进行更改,但是当您可以修复ID问题时这似乎过于复杂,这会更有意义。
答案 4 :(得分:1)
也许简单直接的解决方案是使用uniqueid()php或其他编程语言替代函数。
答案 5 :(得分:0)
与接受的答案不同,我同意FantomX1提出的解决方案,为每个复选框生成一个随机ID,并将该ID用于与该复选框关联的标签。 但我会使用uuid生成随机ID(请参见Create GUID / UUID in JavaScript?)