我正在尝试构建一种直接的方法来选择表格中的单元格。选择取决于使用鼠标拖动的起点和终点,类似于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>
答案 0 :(得分:1)
一种解决方法是在对副本进行排序和排序之前复制坐标数组,并使用复制结果对行和单元格进行切片。
另一个是使用Math.max&amp; 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;
});
&#13;
#pixels {
border-collapse: collapse;
}
#pixels td {
border: 1px solid black;
width: 64px;
height: 64px;
}
#pixels td.selected {
outline: 3px solid red;
}
&#13;
<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>
&#13;