基于点击位置实现两行表格单元格批量交换的jQuery方案求助
实现两行前N个单元格批量交换的解决方案
我来帮你搞定这个需求——选中两行对应位置的单元格后,交换每行从开头到该位置的所有td。咱们主要改两个地方:选中逻辑的校验和批量交换的核心代码。
第一步:优化选中逻辑,确保选中同列不同行的单元格
原来的选中逻辑没有限制必须是同列,所以先修改点击事件,让用户只能选中两行里同一列的单元格,如果选了其他位置的,就清空之前的选中状态,避免无效操作:
$(function() { $("table td:not(.notSelectable)").click(function() { const currentCell = $(this); const currentRow = currentCell.parent('tr'); const colIndex = currentCell.index(); // 获取当前单元格的列位置 // 检查是否已经选中了另一行同列的单元格 const matchedSelected = $(".selected, .lastSelected").filter(function() { return !$(this).parent('tr').is(currentRow) && $(this).index() === colIndex; }); if (matchedSelected.length === 1) { // 已经有同列的选中项,切换选中状态 $(".lastSelected").removeClass("lastSelected"); $(".selected").toggleClass("selected lastSelected"); currentCell.addClass("selected"); } else { // 没找到匹配的同列项,清空之前选中,只选当前单元格 $(".selected, .lastSelected").removeClass("selected lastSelected"); currentCell.addClass("selected"); } }); });
第二步:重写swap函数,实现批量交换
原来的swap是交换单个单元格,现在改成获取选中的列索引,然后遍历从第0列到该索引的所有列,逐个交换两行对应位置的td内容:
function swap() { const selectedCells = $(".selected, .lastSelected"); if (selectedCells.length !== 2) { alert("请选中两行中同一列的两个单元格哦!"); return; } // 校验两个单元格是否是不同行同列 const cellA = selectedCells.eq(0); const cellB = selectedCells.eq(1); const rowA = cellA.parent('tr'); const rowB = cellB.parent('tr'); const targetCol = cellA.index(); if (rowA.is(rowB) || cellB.index() !== targetCol) { alert("必须选中两行里同一列的单元格才行!"); return; } // 遍历从第0列到目标列,逐个交换对应单元格的内容 for (let i = 0; i <= targetCol; i++) { const tdFromRowA = rowA.find('td').eq(i); const tdFromRowB = rowB.find('td').eq(i); // 交换HTML内容(包含隐藏input的值) const tempContent = tdFromRowA.html(); tdFromRowA.html(tdFromRowB.html()); tdFromRowB.html(tempContent); } // 交换完成后清空选中状态 selectedCells.removeClass("selected lastSelected"); }
完整的修改后代码
把上面的脚本替换原来的<script>部分,完整HTML代码如下:
<html> <style> body{ font-size: 30px; text-align: center; background-color: ivory; } table{ width:100px; } h1{ font-family: Helvetica; font-size: 30px; } th{ border: 10px solid black; padding: 5px; font-size: 70px; } td{ border: 10px solid black; padding: 5px; font-size: 130px; } tr.center, td.center{ text-align: center; } td:not(.notSelectable) { cursor: pointer } td.selected, td.lastSelected { background-color: yellow; color: white; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script> $(function() { $("table td:not(.notSelectable)").click(function() { const currentCell = $(this); const currentRow = currentCell.parent('tr'); const colIndex = currentCell.index(); // 获取当前单元格的列位置 // 检查是否已经选中了另一行同列的单元格 const matchedSelected = $(".selected, .lastSelected").filter(function() { return !$(this).parent('tr').is(currentRow) && $(this).index() === colIndex; }); if (matchedSelected.length === 1) { // 已经有同列的选中项,切换选中状态 $(".lastSelected").removeClass("lastSelected"); $(".selected").toggleClass("selected lastSelected"); currentCell.addClass("selected"); } else { // 没找到匹配的同列项,清空之前选中,只选当前单元格 $(".selected, .lastSelected").removeClass("selected lastSelected"); currentCell.addClass("selected"); } }); }); function swap() { const selectedCells = $(".selected, .lastSelected"); if (selectedCells.length !== 2) { alert("请选中两行中同一列的两个单元格哦!"); return; } // 校验两个单元格是否是不同行同列 const cellA = selectedCells.eq(0); const cellB = selectedCells.eq(1); const rowA = cellA.parent('tr'); const rowB = cellB.parent('tr'); const targetCol = cellA.index(); if (rowA.is(rowB) || cellB.index() !== targetCol) { alert("必须选中两行里同一列的单元格才行!"); return; } // 遍历从第0列到目标列,逐个交换对应单元格的内容 for (let i = 0; i <= targetCol; i++) { const tdFromRowA = rowA.find('td').eq(i); const tdFromRowB = rowB.find('td').eq(i); // 交换HTML内容(包含隐藏input的值) const tempContent = tdFromRowA.html(); tdFromRowA.html(tdFromRowB.html()); tdFromRowB.html(tempContent); } // 交换完成后清空选中状态 selectedCells.removeClass("selected lastSelected"); } </script> <body> <button onclick="swap();">Crossover</button> <br /><br /> <table border="1" align = "center"> <tbody> <tr> <td bgcolor = "#4caf50">0<input type="hidden" value="0" /></td> <td bgcolor = "#4caf50">1<input type="hidden" value="1" /></td> <td bgcolor = "#4caf50">1<input type="hidden" value="1" /></td> <td bgcolor = "#4caf50">0<input type="hidden" value="0" /></td> <td bgcolor = "#4caf50">1<input type="hidden" value="1" /></td> <td bgcolor = "#4caf50">0<input type="hidden" value="0" /></td> <td bgcolor = "#4caf50">0<input type="hidden" value="0" /></td> <td bgcolor = "#4caf50">1<input type="hidden" value="1" /></td> <td bgcolor = "#4caf50">1<input type="hidden" value="1" /></td> <td bgcolor = "#4caf50">1<input type="hidden" value="1" /></td> <th>P1</th> </tr> <tr> <td bgcolor ="#ff0000">0<input type="hidden" value="0" /></td> <td bgcolor= "#ff0000">0<input type="hidden" value="0" /></td> <td bgcolor= "#ff0000">0<input type="hidden" value="0" /></td> <td bgcolor= "#ff0000">1<input type="hidden" value="1" /></td> <td bgcolor ="#ff0000">1<input type="hidden" value="1" /></td> <td bgcolor ="#ff0000">1<input type="hidden" value="1" /></td> <td bgcolor= "#ff0000">0<input type="hidden" value="0" /></td> <td bgcolor ="#ff0000">1<input type="hidden" value="1" /></td> <td bgcolor= "#ff0000">1<input type="hidden" value="1" /></td> <td bgcolor= "#ff0000">0<input type="hidden" value="0" /></td> <th>P2</th> </tr> </tbody> </table> </body> </html>
功能说明
- 点击单元格时,系统会自动判断是否已经选中了另一行同列的单元格,符合条件才会保留两个选中状态,否则只保留当前选中的单元格
- 点击「Crossover」按钮时:
- 如果选中数量不对或者不是同列不同行的单元格,会弹出提示
- 符合条件的话,会批量交换两行从第0列到选中列的所有单元格内容(包括隐藏的input值)
- 交换完成后自动清除选中状态,方便下一次操作
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

