我看到another question提出类似的问题,但不同之处在于他们将输入元素放在label
标记内,而我的标记在外面:
<!DOCTYPE html>
<head>
<style>
div {
background-color: #AAA;
width: 100px;
}
</style>
</head>
<body>
<div id='foo' onClick="alert('clicked')">
<label for='foo-pie'>Pick Foo:</label>
<select id='foo-pie' name='wat[wat]'>
<option value='pie'>Foo</option>
</select>
</div>
</body>
</html>
如果我点击div,而不是标签,警报会触发一次。如果我点击标签,警报会触发两次。为什么是这样?在我看来,无论如何警报应该触发一次。如果我删除for=
它只会触发一次,这表明我发生了某种事件冒泡...... JSFiddle
答案 0 :(得分:4)
这是因为label是一个交互元素。单击时,它会在其关联元素上触发激活事件。此激活事件通常会导致单击事件,因此您只需单击两次即可。一个用于实际用户点击,一个用于激活事件。
http://www.w3.org/TR/html5/forms.html#the-label-element
例如,在单击复选框标签的平台上检查 复选框,单击以下代码段中的标签可能会触发 用户代理在输入上运行合成点击激活步骤 元素,就好像元素本身已被用户触发:
<label><input type=checkbox name=lost> Lost</label>
另一方面 平台,行为可能只是集中控制,或做 什么都没有。
虽然文档中的示例显示了输入元素的onClick,但事件会冒出来,所以在您的情况下,您的div会获得冒泡的点击事件
要防止这种情况,您可以阻止默认操作,或使用stopPropagation来阻止事件冒泡。
<强>内联强>
<label onclick="return false;" for='foo-pie'>Pick Foo:</label>
代码
HTML
<label id="foolabel" for='foo-pie'>Pick Foo:</label>
JS
document.getElementById("foolabel").addEventListener(function(e){
e.preventDefault(); //Or
e.stopPropagation();
});
示例强>
<div id='foo' onClick="alert('clicked')">
<label onclick="event.stopPropagation();" for='foo-pie'>Pick Foo:</label>
<select id='foo-pie' name='wat[wat]'>
<option value='pie'>Foo</option>
</select>
</div>
&#13;
答案 1 :(得分:0)
我的理论是,这是一个称为事件传播的功能,通过使用<div>
属性定义onclick
,它也会以某种方式将该事件绑定到孩子身上。
尝试将e.stopPropagation
投放到您的事件回调中,并且应该阻止它被多次调用。