我正在尝试构建一种简单的方法来选择表格中的单元格。选择取决于用鼠标拖动的起始点和结束点,类似于它在Excel中的工作方式。
只要您从左到右、从上到下拖动,我的当前解决方案就能工作。我试图通过对坐标进行排序来反驳这一点,但这并没有帮助。相反,现在总是按照拖动的方向(水平或垂直)选择两个单元格。我好像搞不懂为什么。
主要的想法是:
我觉得我在思考错误,但我看不出是哪一个。
function markSelection(selection) {
// Sort coordinates (start-end point) numerically
selection["x"] = selection["x"].sort(sortNumbers);
selection["y"] = selection["y"].sort(sortNumbers);
// Only get relevant rows within range
const rows = $("#pixels>tbody tr").slice(selection["y"][0], selection["y"][1] + 1);
$("#pixels>tbody tr td").removeClass("selected");
let cells = $();
// In each relevant row, get the relevant cells
rows.each(function(i, el) {
cells = cells.add($(el).children("td").slice(selection["x"][0], selection["x"][1] + 1));
});
cells.addClass("selected");
}
function sortNumbers(a, b) {
return a - b;
}
let isDragging = false;
let selection = {};
$("#pixels").on("mousedown", "td", function() {
// Start dragging
isDragging = true;
const $this = $(this);
selection["x"] = [$this.index(), $this.index()];
selection["y"] = [$this.parent("tr").index(), $this.parent("tr").index()];
markSelection(selection);
}).on("mouseover", "td", function() {
if (isDragging) {
const $this = $(this);
selection["x"][1] = $this.index();
selection["y"][1] = $this.parent("tr").index();
markSelection(selection);
}
}).on("mouseup", "td", function() {
// End dragging
isDragging = false;
const $this = $(this);
selection["x"][1] = $this.index();
selection["y"][1] = $this.parent("tr").index();
markSelection(selection);
}).on("mouseleave", function() {
// End dragging
isDragging = false;
});#pixels {
border-collapse: collapse;
}
#pixels td {
border: 1px solid black;
width: 64px;
height: 64px;
}
#pixels td.selected {
outline: 3px solid red;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="pixels">
<tbody style="background-color: rgb(255, 255, 255);">
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
</tbody>
</table>
发布于 2017-12-13 15:00:27
修复的一种方法是在排序和排序副本之前创建坐标数组的副本,并使用复制结果对行和单元格进行切片。
另一个方法是使用Math.max & Math.min来获得开始/结束,而不是排序。
对原始数组的排序是在向上移动或向左移动时切换起始点和结束点而导致问题的原因。
function markSelection(selection) {
// make copies before sorting
const coords = {
x: selection["x"].slice().sort(sortNumbers),
y: selection["y"].slice().sort(sortNumbers)
}
// Only get relevant rows within range
const rows = $("#pixels>tbody tr").slice(coords["y"][0], coords["y"][1] + 1);
$("#pixels>tbody tr td").removeClass("selected");
let cells = $();
// In each relevant row, get the relevant cells
rows.each(function(i, el) {
cells = cells.add($(el).children("td").slice(coords["x"][0], coords["x"][1] + 1));
});
cells.addClass("selected");
}
function sortNumbers(a, b) {
return a - b;
}
let isDragging = false;
let selection = {};
$("#pixels").on("mousedown", "td", function() {
// Start dragging
isDragging = true;
const $this = $(this);
selection["x"] = [$this.index(), $this.index()];
selection["y"] = [$this.parent("tr").index(), $this.parent("tr").index()];
markSelection(selection);
}).on("mouseover", "td", function() {
if (isDragging) {
const $this = $(this);
selection["x"][1] = $this.index();
selection["y"][1] = $this.parent("tr").index();
markSelection(selection);
}
}).on("mouseup", "td", function() {
// End dragging
isDragging = false;
const $this = $(this);
selection["x"][1] = $this.index();
selection["y"][1] = $this.parent("tr").index();
markSelection(selection);
}).on("mouseleave", function() {
// End dragging
isDragging = false;
});#pixels {
border-collapse: collapse;
}
#pixels td {
border: 1px solid black;
width: 64px;
height: 64px;
}
#pixels td.selected {
outline: 3px solid red;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="pixels">
<tbody style="background-color: rgb(255, 255, 255);">
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
<tr>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
<td style="border-color:#000000;"></td>
</tr>
</tbody>
</table>
https://stackoverflow.com/questions/47794921
复制相似问题