Ситуация такая:
Я навожу курсор на любую ячейку таблицы и хочу получать массив(список/объект, вообще не важно) с соседними ячейками. Таблица при этом может быть отформатирована как угодно.
На самом деле есть решение(точнее идея) с координатами ячеек, но хотелось бы узнать ещё способы.
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>
У элемента 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
как previousElementSibling
и nextElementSibling
- они ссылаются на предыдущий и следующий tr
, соответственно.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Я делаю всплывающее окно, над кнопкой, при успешном добавлении в корзинувсе вроде работает, но проблема если товар находится в слайдере, slick
Имеем: Сервер Wildfly, управление транзакциями - контейнерИспользуется XA транзакция
Как можно корректно отобразить объекты JBox2D с помощью обычных функций Graphics2D, которые находятся в стандартной Java библиотеке?