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

JQuery动态添加复选框问题:新增主分类下Add Section按钮失效

解决动态生成主分类内「Add Section」按钮失效问题

问题核心原因

你碰到的主要问题是事件绑定时机不匹配:页面加载时用$('.js-add-split').click(...)绑定的事件,只能对当时已存在的按钮生效;而后续通过「Create New Category」动态生成的按钮,并没有被绑定事件。另外还有两个小坑:全局共享的count会导致所有主分类的section计数混乱,以及前端JS模板里不能直接写Razor的@for循环(Razor是服务器端渲染逻辑,JS是客户端执行,动态生成时没法再触发服务器端代码)。

分步解决方案

1. 改用事件委托绑定按钮事件

把事件绑定到页面加载时就存在的静态父元素(比如.sup-content),这样所有后续动态生成的.js-add-split按钮都能触发事件:

// 替换原来的$('.js-add-split').click(...)写法
$('.sup-content').on('click', '.js-add-split', function() {
  // 后续逻辑写在这里
});

2. 为每个主分类维护独立的section计数

不要用全局count变量,而是给每个主分类添加数据属性存储当前section数量:

  • 初始主分类的.services__supnisation标签添加data-section-count="1"
  • 动态生成新主分类时也带上这个属性

3. 提前把服务器端的numOfCheckboxes值传到前端

前端JS里没法执行Razor循环,所以在页面加载时把这个值存在全局变量里:

<!-- 在页面头部添加这段脚本 -->
<script>
  // 从服务器端获取复选框数量计算结果
  const numOfCheckboxes = @((int)TempData["Counter"] * 4 - 1);
</script>

4. 修正新section的插入位置

确保新section添加到当前点击按钮所在的主分类内,而不是全局的最后一个位置。

修改后的完整代码

初始主分类(添加数据属性)

<div class="services-content sup-content">
  <div class="services__supnisation" data-section-count="1">
    <!-- 原输入框、复选框区域代码不变 -->
    <div class="services-actions">
      <button type="button" class="mdl-button secondary-btn secondary-btn-border add-split-btn js-add-split mdl-js-button mdl-js-ripple-effect">
        Add Section
      </button>
    </div>
  </div>
  <!-- New Category should be added here -->
</div>

「Create New Category」按钮的JS代码(修正计数与HTML生成逻辑)

$('.js-create-sup').click(function () {
  // 计算新主分类的ID
  const categoryCount = $('.services__supnisation').length + 1;
  // 前端生成复选框HTML
  let checkboxesHtml = '';
  for (let j = 1; j <= numOfCheckboxes; j++) {
    checkboxesHtml += `
      <li>
        <input type="checkbox" id="sup-${j}-${categoryCount}">
        <label for="sup-${j}-${categoryCount}"><i class="icon-tick" disabled></i></label>
      </li>
    `;
  }
  // 组装新主分类的HTML
  const supContent = `
    <div class="services__supnisation" data-section-count="1">
      <div class="services__supnisation-title">
        <input type="text" id="sup-title-${categoryCount}" class="sup-title js-sup-title" value="sup ${categoryCount}">
      </div>
      <div class="services-item js-splits-item">
        <ul>${checkboxesHtml}</ul>
        <div class="services-item__footer">
          <small class="services-item__availability">
            <span class="title">Section 1</span>
          </small>
        </div>
      </div>
      <div class="services-actions">
        <button type="button" class="mdl-button secondary-btn secondary-btn-border add-split-btn js-add-split mdl-js-button mdl-js-ripple-effect">
          Add Section
        </button>
      </div>
    </div>
  `;
  // 插入到最后一个主分类后面
  $(supContent).insertAfter($('.sup-content .services__supnisation').last());
});

「Add Section」按钮的完整事件代码

// 提前从服务器端获取的复选框数量
const numOfCheckboxes = @((int)TempData["Counter"] * 4 - 1);

$('.sup-content').on('click', '.js-add-split', function() {
  // 定位当前点击按钮所属的主分类
  const $parentCategory = $(this).closest('.services__supnisation');
  // 获取并更新当前主分类的section计数
  let sectionCount = parseInt($parentCategory.data('section-count')) + 1;
  $parentCategory.data('section-count', sectionCount);
  // 提取主分类ID(从输入框ID中拆分)
  const categoryId = $parentCategory.find('.js-sup-title').attr('id').split('-')[2];
  
  // 生成新section的复选框HTML
  let checkboxesHtml = '';
  for (let j = 1; j <= numOfCheckboxes; j++) {
    checkboxesHtml += `
      <li>
        <input type="checkbox" id="sup-${j}-${categoryId}-${sectionCount}">
        <label for="sup-${j}-${categoryId}-${sectionCount}"><i class="icon-tick" disabled></i></label>
      </li>
    `;
  }
  
  // 组装新section的HTML
  const splitContent = `
    <div class="services-item js-splits-item">
      <ul>${checkboxesHtml}</ul>
      <div class="services-item__footer">
        <small class="services-item__availability">
          <span class="title">Section ${sectionCount}</span>
        </small>
      </div>
    </div>
  `;
  
  // 插入到当前主分类内的最后一个section后面
  $(splitContent).insertAfter($parentCategory.find('.js-splits-item').last());
  
  // 在这里保留你原有的复选框勾选验证逻辑即可
});

关键改动说明

  • 事件委托:通过静态父元素监听点击,确保动态生成的按钮也能触发事件
  • 独立计数:每个主分类用data-section-count存储自己的section数量,避免全局变量冲突
  • 客户端生成HTML:把Razor的循环逻辑移到前端JS,解决服务器端代码无法在客户端动态执行的问题
  • 精准插入:通过closest('.services__supnisation')定位当前主分类,确保新section添加到正确位置

内容的提问来源于stack exchange,提问作者ExpertGenie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:08:10