smi*_*omb 8 html javascript css jquery javascript-events
我正在尝试设置复选框列表的样式.我添加了我的样式,它们在渲染时显示正确.我想在单击复选框的标签时添加一个类.这是我的标记,这在jsfiddle中是相同的.您可以从我的小提琴中看到,只需单击一下即可注册两个点击事件.为什么?
HTML:
<ul>
<li>
<label for="test_0" class="">
<input id="test_0" name="offering_cycle" type="checkbox" value="1"> Fall
</label>
</li>
<li>
<label for="test_1" class="">
<input id="test_1" name="offering_cycle" type="checkbox" value="2"> Spring
</label>
</li>
<li>
<label for="test_2" class="">
<input id="test_2" name="offering_cycle" type="checkbox" value="3"> Summer
</label>
</li>
<li>
<label for="test_3" class="">
<input id="test_3" name="offering_cycle" type="checkbox" value="4"> Other
</label>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
CSS:
ul {
list-style-type:none;
}
label {
position:relative;
display:inline-block;
padding-left:27px;
height:25px;
}
label:before {
display:block;
position:absolute;
top:-2px;
margin-left:-28px;
width:18px;
height:18px;
background-color:#fff;
border-radius:5px;
border:1px solid #ccc;
text-align: center;
color:#fff;
font-size:18px;
content:'a';
}
input {
width:1px;
height:1px;
border:0;
opacity:0;
float:right;
}
Run Code Online (Sandbox Code Playgroud)
jQuery的:
$('label[for*=test_]').on('click',function(){
$(this).toggleClass('testing');
});
Run Code Online (Sandbox Code Playgroud)
标签的点击处理程序被调用两次的原因:
单击与输入关联的标签会触发两个单击事件。为标签触发第一个点击事件。该单击事件的默认处理会导致为关联的输入触发第二个单击事件。由于您将输入作为标签的后代,因此第二个单击事件会冒泡到标签。这就是为什么您的点击事件处理程序被调用两次的原因。
如果您真的想处理标签的点击事件(并且只为一次点击执行一次):
(1) 如果您愿意并且能够修改 HTML,您可以移动输入,使其不是标签的后代。仍然会有两个点击事件,但第二个点击事件不会从输入冒泡到标签,因为标签不再是输入的祖先。
当输入不是标签的后代时,您必须使用标签的“for”属性将其与输入相关联。“for”属性的值应该是输入的“id”值。(您已经包含了具有正确值的“for”属性。)
<input id="test_0" name="offering_cycle" type="checkbox" value="1">
<label for="test_0" class="">Fall</label>
Run Code Online (Sandbox Code Playgroud)
(2) 防止第一个点击事件的默认处理可以防止第二个点击事件被触发,但这样做会破坏标签。也就是说,单击标签时不会选中/取消选中复选框。
$('label[for*=test_]').on('click', function(event) {
event.preventDefault();
$(this).toggleClass('testing');
// returning false would be another way to prevent the default handling.
});
Run Code Online (Sandbox Code Playgroud)
(3) 相反,您可以阻止第二个点击事件从输入中冒泡。
$('input:checkbox').on('click', function(event) {
event.stopPropagation();
});
$('label[for*=test_]').on('click', function() {
$(this).toggleClass('testing');
});
Run Code Online (Sandbox Code Playgroud)
注意:如果输入不是标签的子元素,则没有必要这样做。
(4) 或者您可以检查处理程序中的事件目标。它将是第一个点击事件的标签和第二个点击事件的输入。以下处理程序仅针对第一个单击事件执行 if 语句中的代码。
$('label[for*=test_]').on('click', function(event) {
if (event.target == this) {
$(this).toggleClass('testing');
}
});
Run Code Online (Sandbox Code Playgroud)
注意:如果输入不是标签的子元素,上面的代码仍然可以工作,但 if 语句将是不必要的,因为为输入触发的点击事件不会冒泡到标签。
改为处理输入的点击:
在您的情况下,您实际上并不需要为 label 元素注册点击处理程序。您可以为输入注册一个单击(或更改)处理程序。然后您可以使用$(this).closest('label')来获取标签元素。
$('input[name=offering_cycle]').on('click', function() {
$(this).closest('label').toggleClass('testing');
});
Run Code Online (Sandbox Code Playgroud)
注意:如果输入不是标签的子元素,则在您单击标签时仍会调用上面的处理程序,但$(this).closest('label')不会获取标签。你将不得不使用类似的东西$('label[for="' + this.id + '"]')。
关于标签元素上的“for”属性:
由于您在标签中有输入,因此没有必要for在标签上包含属性 --- 但它并非无效。
您已将“for”属性值设置为输入元素的“id”属性值。这是使用“for”属性将标签与输入关联的正确方法。如果您要包含具有无效值的“for”属性,则即使输入是标签的后代,标签也不会与输入相关联。
来自标签元素“for”属性的HTML5 规范:
可以指定 for 属性来指示与标题相关联的表单控件。如果指定了该属性,则该属性的值必须是与该标签元素位于同一文档中的可标签元素的 ID。如果指定了属性,并且文档中存在一个元素的 ID 等于 for 属性的值,并且第一个这样的元素是可标记元素,则该元素是标签元素的标记控件。
如果没有指定 for 属性,但是 label 元素有一个 labelable 元素后代,那么树顺序中的第一个这样的后代是 label 元素的标签控件。
| 归档时间: |
|
| 查看次数: |
2392 次 |
| 最近记录: |