You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击事件与事件冒泡异常:点击li触发两次alert问题

问题分析与解决

场景与问题

现有WPForms单选框的HTML结构如下:

<div id="wpforms-1345-field_6-container" class="wpforms-field wpforms-field-radio row-selection" data-field-id="6">
  <label class="wpforms-field-label" for="wpforms-1345-field_6">What is your age?
    <span class="wpforms-required-label">*</span>
  </label>
  <ul id="wpforms-1345-field_6" class="wpforms-field-required">
    <li class="choice-1 depth-1">
      <input type="radio" id="wpforms-1345-field_6_1" name="wpforms[fields][6]" value="0-15" required="">
      <label class="wpforms-field-label-inline" for="wpforms-1345-field_6_1">0-15</label>
    </li>
    <li class="choice-2 depth-1">
      <input type="radio" id="wpforms-1345-field_6_2" name="wpforms[fields][6]" value="16-25" required="">
      <label class="wpforms-field-label-inline" for="wpforms-1345-field_6_2">16-25</label>
    </li>
    <li class="choice-3 depth-1">
      <input type="radio" id="wpforms-1345-field_6_3" name="wpforms[fields][6]" value="26-35" required="">
      <label class="wpforms-field-label-inline" for="wpforms-1345-field_6_3">26-35</label>
    </li>
    <li class="choice-5 depth-1">
      <input type="radio" id="wpforms-1345-field_6_5" name="wpforms[fields][6]" value="36-45" required="">
      <label class="wpforms-field-label-inline" for="wpforms-1345-field_6_5">36-45</label>
    </li>
    <li class="choice-4 depth-1">
      <input type="radio" id="wpforms-1345-field_6_4" name="wpforms[fields][6]" value="46-100" required="">
      <label class="wpforms-field-label-inline" for="wpforms-1345-field_6_4">≥46</label>
    </li>
  </ul>
</div>

需求是点击<li>即可选中对应的单选框,但无法修改现有HTML结构。编写的jQuery代码如下:

jQuery(function($) {
  $('.row-selection li').on('click', function(event) {
    alert('clicked');
    //   event.preventDefault();
    event.stopPropagation();
    $(this).children('input')[0].click(function(event) {
      alert('bubbledup');
      //    event.preventDefault();
      event.stopPropagation();
    });
  });
});

实际运行时出现两个问题:

  1. 点击<li>会触发两次clicked弹窗;
  2. bubbledup弹窗从未触发。

原因拆解

  1. 两次弹窗的根源
    点击<li>内的<label>时,浏览器会因为<label>的for属性自动触发关联<input>的点击事件。而<input>是<li>的子元素,这个点击事件会向上冒泡到<li>,导致<li>的点击事件被触发两次:一次是点击<label>或<li>空白处的原始事件,另一次是<label>触发<input>点击后冒泡上来的事件。你添加的event.stopPropagation()只阻止了当前事件向上冒泡,没处理<label>触发的额外事件流。

  2. bubbledup不触发的原因
    你在<li>的点击事件里才给<input>绑定点击回调,而同步触发input.click()时,这个回调还没绑定完成,自然不会执行。而且这种绑定方式会导致每次点击<li>都给<input>新增一个点击事件,属于错误用法。

修正后的代码

jQuery(function($) {
  $('.row-selection li').on('click', function(event) {
    // 排除点击input本身的情况,避免重复操作
    if (event.target.tagName !== 'INPUT') {
      const $radio = $(this).find('input[type="radio"]');
      $radio.prop('checked', true);
      // 触发change事件,保证表单数据同步
      $radio.trigger('change');
    }
    event.stopPropagation();
  });

  // 阻止label的默认行为,避免自动触发input点击导致重复事件
  $('.row-selection li label').on('click', function(event) {
    event.preventDefault();
  });
});

内容的提问来源于stack exchange,提问作者Faye D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:45:39