label元素含button与span子元素时点击span意外触发按钮点击事件
当label元素包含同级的button和span子元素时,点击span会意外触发第一个button的点击事件,具体细节如下:
示例代码
JS代码
btn1.addEventListener('click', function() { alert('btn1')}) span1.addEventListener('click', function() { alert('span1')}) btn2.addEventListener('click', function() { alert('btn2')}) span2.addEventListener('click', function() { alert('span2')})
HTML代码
<label> <button id="btn1">Button1</button> <span id = "span1">Span1</span> <button id="btn2">Button2</button> <span id = "span2">Span2</span> </label>
异常现象
- 点击第一个span会同时触发第一个button的点击事件;
- 点击第二个span也会触发第一个button的点击事件(而非第二个button或对应span的事件);
- 将父元素改为span或div则无此异常,仅label作为父元素时出现该问题。
测试环境
- Chrome 116.0.5845.140
- Safari 15.6.1
原因分析
这是label元素的原生交互特性导致的。根据HTML规范,label的核心作用是关联表单控件以提升可访问性。当点击label内部的非表单控件元素时,浏览器会自动将点击行为关联到label所关联的第一个表单控件上。
在当前DOM结构里,label内的第一个表单控件是btn1,所以不管点击label里的哪个非表单控件(比如两个span),浏览器都会模拟触发btn1的点击事件。而button本身属于表单控件,点击时浏览器会直接处理自身的点击逻辑,不会触发label的关联跳转。
需要注意的是,label这种“关联第一个表单控件”的行为是浏览器原生实现,部分文档可能未明确说明多表单控件场景下的这个细节,才导致了预期外的结果。
内容的提问来源于stack exchange,提问作者mwag
相关产品推荐
相关产品推荐

