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

求助:jQuery实现取消复选框后自动勾选同列上一个已选复选框

解决Checkbox取消勾选时自动恢复同列之前选中项的问题

我明白你的需求啦:当手动取消某列的checkbox时,同一category(蓝色框)的该列要自动勾选之前选中的那个选项,保证每列始终有一个选中项。咱们来修改代码实现这个逻辑:

核心思路

  1. 给每个category(.cars)存储每列的最后选中状态,用jQuery的data()方法记录每列对应的选中checkbox ID。
  2. 勾选checkbox时:更新对应列的选中记录,并取消同列其他选项。
  3. 取消checkbox时:不能让列变成无选中状态,直接恢复该列之前记录的选中项,同时确保当前列始终有一个选中项。
  4. 初始化和新增category时,同步设置好初始的列选中记录。

修改后的完整代码

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="js-add-category">Add Category</button>
<br>
<br>
<div class="main">
  <div class="cars">
    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-1" checked>
          <label for="car-1-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-1" checked>
          <label for="car-2-1"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-1" checked>
          <label for="car-3-1"><i class="icon-tick"></i></label>
        </li>
      </ul>
    </div>
    <button type="button" class="js-add-section">Add Section</button>
    <button type="button" class="js-save-section">Save Section</button>
    <br>
    <div class="section">
    </div>
  </div>
  <br>
</div>

CSS

.cars-item {
  border-bottom: 1px solid gray;
}
ul {
  margin: 2px;
}
li {
  display: inline;
}
.cars {
  box-sizing: content-box;
  width: 250px;
  height: auto;
  padding: 10px;
  border: 5px solid blue;
  margin-bottom: 10px;
}

JavaScript

// 全局计数器,生成唯一ID避免重复
let categoryCount = 1;
let sectionCount = 1;

// 初始化第一个category的列选中状态
$('.cars:first').data('columnChecked', {
  0: 'car-1-1',
  1: 'car-2-1',
  2: 'car-3-1'
});

$(".main").on('change', '.js-cars-item [type="checkbox"]', function() {
  const $this = $(this);
  const $category = $this.closest('.cars');
  const idx = $this.closest('li').index(); // 获取当前列的索引
  const isChecked = $this.is(":checked");
  const columnChecked = $category.data('columnChecked') || {};

  if (isChecked) {
    // 勾选时:更新列选中记录,取消同列其他选项
    columnChecked[idx] = $this.attr('id');
    $category.data('columnChecked', columnChecked);
    
    // 取消同列其他checkbox的选中状态
    $category.find('.js-cars-item').each(function() {
      $(this).find(`li:eq(${idx}) [type="checkbox"]`).not($this).prop("checked", false);
    });
  } else {
    // 取消时:恢复该列之前选中的选项,确保列不会空
    const prevCheckedId = columnChecked[idx];
    if (prevCheckedId) {
      $(`#${prevCheckedId}`).prop('checked', true);
    }
    // 强制当前checkbox保持勾选,避免用户误操作导致列无选中
    $this.prop('checked', true);
  }

  // 输出当前选中的checkbox列表
  const checkeds = [];
  $category.find(".cars-item input:checkbox:checked").each(function() {
    checkeds.push($(this).attr('id'));
  });
  console.clear();
  console.log("These are checked:", checkeds);
});

$('.js-add-category').click(function() {
  categoryCount++;
  const categoryId = categoryCount;
  const categoryContent = `
    <div class="cars">
      <div class="cars-item js-cars-item">
        <ul>
          <li>
            <input type="checkbox" id="car-1-${categoryId}" checked>
            <label for="car-1-${categoryId}"><i class="icon-tick"></i></label>
          </li>
          <li>
            <input type="checkbox" id="car-2-${categoryId}" checked>
            <label for="car-2-${categoryId}"><i class="icon-tick"></i></label>
          </li>
          <li>
            <input type="checkbox" id="car-3-${categoryId}" checked>
            <label for="car-3-${categoryId}"><i class="icon-tick"></i></label>
          </li>
        </ul>
      </div>
      <button type="button" class="js-add-section">Add Section</button>
      <button type="button" class="js-save-section">Save Section</button>
    </div>
    <br>
  `;
  const $newCategory = $(categoryContent).appendTo('.main');
  // 初始化新category的列选中状态
  $newCategory.data('columnChecked', {
    0: `car-1-${categoryId}`,
    1: `car-2-${categoryId}`,
    2: `car-3-${categoryId}`
  });
});

$(document.body).on('click', 'button.js-add-section', function() {
  sectionCount++;
  const sectionContent = `
    <div class="cars-item js-cars-item">
      <ul>
        <li>
          <input type="checkbox" id="car-1-${sectionCount}">
          <label for="car-1-${sectionCount}"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-2-${sectionCount}">
          <label for="car-2-${sectionCount}"><i class="icon-tick"></i></label>
        </li>
        <li>
          <input type="checkbox" id="car-3-${sectionCount}">
          <label for="car-3-${sectionCount}"><i class="icon-tick"></i></label>
        </li>
      </ul>
    </div>
  `;
  $(this).closest('.cars').append(sectionContent);
});

$(document.body).on('click', 'button.js-save-section', function() {
  alert('Section saved!');
});

关键修改说明

  1. 状态存储机制:用data('columnChecked')给每个category绑定每列的选中记录,取消操作时能快速定位需要恢复的选项。
  2. 取消逻辑处理:当用户尝试取消勾选时,直接恢复该列之前的选中项,同时强制当前checkbox保持勾选,确保每列始终有一个选中状态。
  3. 唯一ID优化:新增category和section时用计数器生成唯一ID,避免重复ID导致的label关联失效问题。
  4. 初始化同步:初始化和新增category时同步设置初始选中状态,确保功能从一开始就能正常运行。

现在你可以测试一下:不管是勾选新选项,还是尝试取消现有选项,每列都会始终保持一个选中状态,取消操作会自动恢复之前的选中项~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:09:51