html中input放在label中和label用for_id和input绑定的区别探究,涉及到事件传播的冒泡阶段

0 前言

先看我准备的一个示例代码:
<body>
    <form>
        <label id="boyLabel">
            Boy: <input type="radio" name="gender" id="boy" value="boy">
        </label>
        <br>
        <label for="girl">Girl:</label>
        <input type="radio" name="gender" id="girl" value="girl">
    </form>

    <script type="text/javascript">

        const l1 = document.querySelector("#boyLabel");
        const l2 = document.querySelector("label[for=girl]");
        const i1 = document.querySelector("input[value=boy]");
        const i2 = document.querySelector("input[value=girl]");
        console.log(l1);
        console.log(l2);
        console.log(i1);
        console.log(i2);


        l1.addEventListener("click", (e) => {
            console.log("l1 clicked!  LLL1111");
        });
        l2.addEventListener("click", (e) => {
            console.log("l2 clicked!  LLL2222");
        });
        i1.addEventListener("click", (e) => {
             // 这里注意,等下我要把下面的注释符号去掉,让它停止冒泡传播,来对比观察效果
            //   e.stopPropagation();      
             console.log("i1 clicked!  III111");
        });
        i2.addEventListener("click", (e) => {
            e.stopPropagation();
            console.log("i2 clicked!  III222");
        });
    </script>
</body>

我准备了一组关于性别的单选按钮,
采用了label和input标签的两种搭配使用方式,

一种: 对于男孩,采用label内包裹input标签,这种情况下就无需进行input标签先设定id, 然后label内for属性再绑定这个id,形成对应关系

另一种: 对于女孩的选项,采用最正统也就是官方网站示例一般采用的方式, 彼此独立开,用 for id绑定的形式来创建

script 标签内代码逻辑是: 先选定元素,打印出来看看选的对不对,然后分别给他们绑定click事件,便于观察后续的冒泡事件,

1 好戏开始

1.1 先点击 女孩选项的那个input

在这里插入图片描述
在这里插入图片描述
可见,这里只单单触发了 i2 的click 事件

1.2 再点击 女孩选项的那个label

在这里插入图片描述
在这里插入图片描述
这次,因为label和input进行了绑定,所以当我们点击label时,先是label被触发了,之后其绑定的input也被触发了

1.3 这次先点击 男孩选项的那个input

在这里插入图片描述
在这里插入图片描述
先是input标签被点击,没有问题,因为我们直接点的就是那个input, 之后发现,它外面的label也被点击了,这就是因为产生了冒泡的缘故,冒泡到了他的父元素即label标签,同样触发了它的click事件。

对于冒泡阶段不清楚的可以参考我这篇文章:
DOM的三种事件模型和牵扯到的事件e.
其中事件传播处的解释

1.4 再点击 男孩选项的那个label

在这里插入图片描述
在这里插入图片描述
我们发现,点击了label,label先被触发没有问题,然后是其绑定的input,再然后就和上面我们看到的那种情况一样了,因为input在label内部,所以它被触发后,进而冒泡,所以label又被触发了一次,因为冒泡嘛,
这样算下来,就是label会被触发了两次,没必要嘛,所以我们想想办法,毕竟这样比label和input独立开来那种多触发了一次label,

想到了,那就从input入手,阻止它冒泡不就行了

1.5 再点击 男孩选项的那个input 【阻止冒泡后】

把示例代码中 // e.stopPropagation(); 前面的 // 去掉
在这里插入图片描述
在这里插入图片描述
我们发现,label不会被触发了,只有点到的input触发了, 回顾之前,那可是label也要被触发的啊, 效果不错

1.6 再点击 男孩选项的那个label【阻止冒泡后】

在这里插入图片描述

在这里插入图片描述
此时,我们可以看到, 点击了label, label先触发,然后是它绑定的input,然后就没有了,如我们所愿,这样就和input,label都独立出来的女孩的那种现象一致了,也没有多余的触发,

2 那两种到底有什么区别呢?

就是没啥区别,唯一的一个优点吧,就是input嵌套在label里, 这样你就不用写for,id的绑定了,更方便一点,其他的样式什么的,都该怎么调怎么设置,

大家可以参考下这个问答:

Should I put input elements inside a label element?.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值