javascript - 为什么这里的alert会执行2次?
黄舟
黄舟 2017-04-11 10:15:36
[JavaScript讨论组]

这是一个把radio修饰后的按钮组,实现按下一个按钮,颜色变深,再按另一个按钮,之前变深的按钮恢复,此刻被按的按钮变深色。
绑定事件中的alert(value);会提示2次?请问是怎么回事?
CSS部分可忽略,直接看最后jquery。





toggle radio






黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回复(8)
巴扎黑

这个原因很有意思,我开始以为是事件冒泡。但是想想不对。然后代码改为:

$('label').click(function(event){
        console.log(event.target.type);
        $(this).children('span').addClass('input-checked');
        var value = $(this).children('input').val();
        $(this).parent('.toggle').siblings('.toggle').children('label').children('span').removeClass('input-checked');
        console.log(value);
    });

event.target.type主要是这个会触发两个一个是undefined一个是radio。因为label关联的radio也被有一个关联操作。当label被点击时,默认radio也被点击了一次。
解决方法你可以

<p class="label">
   <input type="radio" name="toggle" value="s01e03">
   <span>s01e03</span>
</p>
$('.label').click(function(){});

其实也可以这样写,因为你本身就是要控制span,所以直接绑定到span上。

$('span').click(function () {
    var i = $('span').index($(this));
    $(this).addClass('input-checked');
    var value = $('input').eq(i).val();
    $('span').not($(this)).removeClass('input-checked');
    console.log(value);
})

然后DOM结构不需要改。

迷茫

这样写

<script>
    $('input[type="radio"]').click(function(e){
        $(this).parents('p').siblings().find('span').removeClass('input-checked');
        $(this).parent().find('span').addClass('input-checked');
        var value = $(this).val();
        console.log(value);
    });
</script>
伊谢尔伦

js 没问题,是你css的问题

.toggle label {
    /*float:left;*/
    width:4.0em;
    position: relative;
}
.toggle label input {
    position:absolute;
    top:0px;
    left: 0px;
    width:50px;
    height: 20px;
    z-index: 9999;
    opacity: 0;
}

这俩个换了就好了

巴扎黑

相当于函数执行了两次
去掉input标签后者把input标签放在label外面后表现正常,只执行一次。
或者在后面加上return false 或者$('label').click(function(event){

event.stopPropagation();

});
我猜可能还是事件冒泡引起的,当你点击的时候,首先点击的是input标签,因为这个标签要获得焦点,然后才冒泡到label标签上。 所以执行了两次click事件

阿神

后面加上return false就好了。应该是label标签上面点击事件冒泡了,奇怪的是,换成span或者input就没有这个问题。

大家讲道理

为什么执行两次上面已经有解释了。不过建议将click事件换成change事件

大家讲道理

看了一下别人的评论,综合了一下,我觉得,这个问题的产生不是由于事件冒泡,而是由于label标签的使用(而且我觉得楼主这段代码$(this).parent('.toggle').siblings('.toggle').children('label').children('span').removeClass('input-checked');可以不用写呀。)。可以通过以下方式证明:
1.证明不是事件冒泡,使用 jQuery中的stopPropagation() 方法可以只阻止一个事件起泡。
js代码如下修改:

$('label').click(function(event){
    //$(this).children('span').addClass('input-checked');
    console.log(event.target);
    var value = $(this).children('input').val();
    //$(this).children('span').removeClass('input-checked');
    //alert(value);
    //console.log(value);
    //alert(value);
    //return false;
    event.stopPropagation();
});

会发现输出的结果是:<span>s01e01</span><input type="radio" value="s01e01" name="toggle">
不加该段代码也是这样的,因此不是事件冒泡行为。至于有的层主说用return false,它是阻止了默认的行为(在这里叫做关联行为吧哈哈,是由于label把span和input关联在一起,用return false是取消了关联行为吧)。
2.证明是由于label的关联效果。
我将楼主的代码修改为如下:

<body>

<p class="toggle">
    <p class="p"><input type="radio" name="toggle" value="s01e01"><span>s01e01</span></p>    
</p>
<p class="toggle">
    <label><input type="radio" name="toggle" value="s01e02"><span>s01e02</span></label>
</p>
<p class="toggle">
    <label><input type="radio" name="toggle" value="s01e03"><span>s01e03</span></label>
</p>

</body>
</html>
<script>
$('.p').click(function(){
   //$(this).children('span').addClass('input-checked');
   console.log(event.target);
});
</script>

测试一下就会发现点不同的地方就会展示三个不同的结果:
<span>s01e01</span>、
<input type="radio" name="toggle" class="radio" value="s01e01">、
<p class="p"><input type="radio" name="toggle" class="radio" value="s01e01"><span>s01e01</span></p>。
成功解除了由于label的绑定。

其中有一层只是加了class属性把label标签换成.radio,这种做法是比较好的解决办法

PHP中文网

楼上说的对,labal 和 input 的关系很特殊。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号