将事件绑定到<label>而不事件然后触发两次

时间:2017-12-12 20:30:52

标签: javascript html5 forms label addeventlistener

我有一个<label>附加了::after伪元素,我希望将click事件绑定到该元素。

<label for="my-input">
    <input id="my-input" />
</label>

由于伪元素不是DOM的一部分,我显然不能这样做,因此我将click事件绑定到<label>

但是......我们都知道<label>做了什么,对吧?是的,它重新聚焦光标在<input>

所以,如果你已经猜到会发生什么事情,那就做得很好 - 事件会发生两次

为什么呢?因为当用户点击<label>然后时它会触发一次,浏览器会自动点击<input>(重新定位光标)并最终触发事件第二次。

我很想知道是否有任何创造性的方法。

通常情况下,您可以在冒泡阶段停止事件触发,方法是将useCapture末尾的.addEventListener()布尔标志从false更改为true - 但是在这种情况下,当浏览器自动点击<label>时,不会停止事件(绑定到<input>)第二次触发。

工作示例:

&#13;
&#13;
var myInput = document.querySelector('label[for="my-input"]');

var clickNumber = 1;

function clickDetected(event) {
    
    console.log('Click ' + clickNumber + ' detected');
    clickNumber++;
}

myInput.addEventListener('click', clickDetected, false);
&#13;
label {
position: relative;
top: 48px;
width: 200px;
height: 100px;
margin: 24px 6px;
padding: 24px;
background-color: rgb(255, 0, 0);
}

label[for="my-input"]::after {
content: '+';
position: absolute;
display: block;
top: -26px;
right: 4px;
width: 22px;
height: 22px;
color: rgb(255, 255, 255);
font-size: 21px;
line-height: 22px;
font-weight: bold;
text-align: center;
background-color: rgb(255, 0, 0);
border-radius: 2px;
box-shadow: 3px 3px 3px rgba(0, 75, 165, 0.4);
cursor: pointer;
}
&#13;
<label for="my-input">
<input id="my-input" type="text" />
</label>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

这样做:

var myInput = document.querySelector('label[for="my-input"]');

var clickNumber = 1;

function clickDetected(e) {


}

myInput.onclick = function (e) {
    if (e.target.getAttribute('id') === 'label') {
    console.log('Click ' + clickNumber + ' detected');
    clickNumber++;
    }
}
label {
position: relative;
top: 24px;
width: 200px;
height: 100px;
margin: 24px 6px;
padding: 24px;
background-color: rgb(255, 0, 0);
}
<label for="my-input" id="label">
<input id="my-input" type="text" />
</label>