首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用jQuery拖动后,在表中选择范围内的单元格

使用jQuery拖动后,在表中选择范围内的单元格
EN

Stack Overflow用户
提问于 2017-12-13 14:04:30
回答 1查看 1.1K关注 0票数 0

我正在尝试构建一种简单的方法来选择表格中的单元格。选择取决于用鼠标拖动的起始点和结束点,类似于它在Excel中的工作方式。

只要您从左到右、从上到下拖动,我的当前解决方案就能工作。我试图通过对坐标进行排序来反驳这一点,但这并没有帮助。相反,现在总是按照拖动的方向(水平或垂直)选择两个单元格。我好像搞不懂为什么。

主要的想法是:

  • onmousedown:使用行和单元格idnex存储起始单元的坐标
  • onmouseover/onmouseleave:存储结束单元格的坐标
  • 在每个事件中,切分行及其子行,以获得由坐标所给出的正确范围。

我觉得我在思考错误,但我看不出是哪一个。

代码语言:javascript
复制
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;
});
代码语言:javascript
复制
#pixels {
  border-collapse: collapse;
}

#pixels td {
  border: 1px solid black;
  width: 64px;
  height: 64px;
}

#pixels td.selected {
  outline: 3px solid red;
}
代码语言:javascript
复制
<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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-13 15:00:27

修复的一种方法是在排序和排序副本之前创建坐标数组的副本,并使用复制结果对行和单元格进行切片。

另一个方法是使用Math.max & Math.min来获得开始/结束,而不是排序。

对原始数组的排序是在向上移动或向左移动时切换起始点和结束点而导致问题的原因。

代码语言:javascript
复制
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;
});
代码语言:javascript
复制
#pixels {
  border-collapse: collapse;
}

#pixels td {
  border: 1px solid black;
  width: 64px;
  height: 64px;
}

#pixels td.selected {
  outline: 3px solid red;
}
代码语言:javascript
复制
<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>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47794921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档