label中包含input,绑定在label的事件触发两次

今天同事遇到这个很奇怪的问题,深入探查了一下,才发现其中奥妙。
最初怀疑是重复绑定造成的,但精简代码到最小,仍然出现。在排查了jQuery版本,css覆盖层,各种能想到的可能性后,仍一筹莫展。
静下心来慢慢梳理,通过输出事件来源,才猛然发现,原来绑定不同的元素,其事件来源是不同的。

找到了事件来源,似乎看到了蛛丝马迹,赶紧顺藤摸瓜。推测如下:
1.绑定在label。单击input后,触发input本身的click事件。单击label后,首先触发label本身的click事件,然后由于“某种原因”触发了input的click事件,进而事件冒泡至label,再次触发label的click事件。
2.绑定在input。单击input后,触发input本身的click事件。单击label后,由于“某种原因”触发了input的click事件。

将该示例在IE8-11、chrome中测试,表现相同。突然想起来,label是有一个for属性,标准的用法如下:

标准用法中,单击label,仍会触发input的click事件。

对以上两个示例进一步测试,替换input:radio为其他类型(如input:checkbox或input:text),表现相同。
由此可以得出结论,上述“某种原因”,是浏览器的特性。当单击与input相关(嵌套或for属性指定)的label时,自动触发input的click事件。

原来是个之前从未留意过的“坑”,如果不是今天遇到,还不知要潜伏多久。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注