RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 817501
Accepted
LiaVa
LiaVa
Asked:2020-04-22 14:12:57 +0000 UTC2020-04-22 14:12:57 +0000 UTC 2020-04-22 14:12:57 +0000 UTC

如何获取相邻的表格单元格?

  • 772

情况是这样的:

我将鼠标悬停在任何表格单元格上,并希望获得一个包含相邻单元格的数组(列表/对象,根本不重要)。表格可以随意格式化。

事实上,有一个解决方案(更准确地说,一个想法)与单元格坐标,但我想知道更多的方法。

javascript
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. yar85
    2020-04-22T15:01:17Z2020-04-22T15:01:17Z

    对于元素td,属性parentElement指向父元素tr。
    而对于元素tr,该属性children包含子元素的集合td。

    var table = document.getElementById('my-table'); 
    for (let td of table.querySelectorAll('td')) 
      td.addEventListener('mouseenter', showSiblings);
    
    function showSiblings() {
      let str = '', 
          siblings = this.parentElement.children; 
      for (let td of siblings) {
        if (td === this)
          str += ` [${td.textContent}]`; 
        else
          str += `  ${td.textContent} `;  
      }
      console.clear(); 
      console.log(str); 
    }
    table { border-collapse: collapse; text-align: center; }
       td { width: 50px; height: 30px; border: 1px solid #ccc; }
    <table id="my-table">
      <thead></thead>
      <tbody>
        <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
        <tr><td>5</td><td>6</td><td>7</td><td>8</td></tr>
        <tr><td>9</td><td>10</td><td>11</td><td>12</td></tr>
        <tr><td>13</td><td>14</td><td>15</td><td>16</td></tr>
      </tbody>
    </table>

    如果还需要接收上/下行中的单元格,那么您可以使用和- 它们分别引用上一个和下一个tr这样的元素属性。previousElementSiblingnextElementSiblingtr

    • 3
  2. Best Answer
    vihtor
    2020-04-22T15:04:26Z2020-04-22T15:04:26Z

      const $table = document.querySelector('table');
      const $input = document.querySelector('input');
      const $span = document.querySelector('span');
    
      $table.addEventListener('mousemove', onMove);
      $input.addEventListener('change', onChange);
    
      function clean() {
        const $actives = $table.querySelectorAll('.active');
        const $neighbours = $table.querySelectorAll('.neighbour');
    
        $actives.forEach($active => $active.classList.remove('active'));
        $neighbours.forEach($neighbour => $neighbour.classList.remove('neighbour'));
      }
    
      function indexOf($element) {
        return Array.prototype.slice.call($element.parentElement.children).indexOf($element);
      }
    
      function onChange() {
        $span.innerHTML = $input.value;
      }
    
      onChange();
    
      function onMove(event) {
        const $target = event.target;
    
        if ($target.tagName !== 'TD' || $target.classList.contains('active')) {
          return;
        }
    
        const far = parseInt($input.value);
        const neighbours = getNeighbors($target, far);
    
        clean();
    
        $target.classList.add('active');
        neighbours.forEach(neighbour => neighbour.classList.add('neighbour'));
      }
    
      /**
       * Получить соседей ячейки
       * @param {HTMLTableCellElement} $cell Исходня ячейка
       * @param {Number} far На сколько далёких соседей нужно получить
       * @return {HTMLTableCellElement[]}
       */
      function getNeighbors($cell, far = 1) {
        // выбираем строку ячейки
        const $row = $cell.parentElement;
        // выбираем элемент, который держит все строки (обычно это <table> или <tbody>)
        const $wrapper = $row.parentElement;
    
        // находим индекс исходной ячеки
        const index = [
          indexOf($row), // индекс строки
          indexOf($cell) // индекс ячейки
        ];
    
        // вычисляем ограничивающий "ящик"
        const bbox = [
          Math.max(index[0] - far, 0), // индекс минимальной строки
          Math.max(index[1] - far, 0), // индекс минимальной ячейки
          Math.min(index[0] + far, $wrapper.children.length - 1), // индекс максимальной строки
          Math.min(index[1] + far, $row.children.length - 1) // индекс максимальной ячейки
        ];
    
        // массив с результатом
        const list = [];
    
        // перебираем все строки из bbox
        for (let i = bbox[0]; i < bbox[2] + 1; i++) {
          const $sRow = $wrapper.children.item(i);
    
          // в рамках каждой строки, перебираем все ячейки из bbox
          for (let j = bbox[1]; j < bbox[3] + 1; j++) {
    
            // если сейчас ячейка является исходной, пропускаем её
            if (i === index[0] && j === index[1]) {
              continue;
            }
    
            const $sCell = $sRow.children.item(j);
    
            list.push($sCell);
          }
        }
    
        return list;
      }
    table {
      border: 1px;
    }
    
    td {
      width: 30px;
      height: 30px;
      content: '';
      border: 1px solid green;
    }
    
    td.active {
      background: #ff0000;
    }
    
    td.neighbour {
      background: #ff9999;
    }
    <input type="range" min="0" max="5" step="1" value="1">
    <span></span>
    <table>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </table>

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5