Редактор и html-таблица
Здравствуйте!
Расширяю функционал редактора, чтоб в модальном окне удобно заполнять таблицы. Основное получилось быстро написать, а вот на целый день застрял с объединением ячеек таблицы. Не знаю как выделять ячейки таблицы, чтоб мышкой с нажатой левой клавишей можно было выделять ячейки, а потом нажав кнопку "Объединить ячейки" они объединились. Накидал вот такое, знаю что не правильно. У меня пока нет идей как это сделать. Не могу выделить ячейки, чтоб дойти до того какой атрибут ставить colspan или rowspan.
<style>td.cell__active {background:#7fffd4}table, th, td{min-width:50px;border:solid 1px #ccc} th, td{min-width:50px;min-height:15px}button{margin-top:10px}</style>
<table contenteditable="true">
<tbody>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
</tbody>
</table>
<button id="margeTd">Объединить ячейки</button>
<script>
let table = document.querySelector('table');
// Добавить класс ячейкам таблицы
table.addEventListener('mouseover', function(e) {
if (e.target.tagName == 'TD') {
e.target.className = 'cell__active';
}
});
// Объединение ячеек таблицы
document.querySelector('#margeTd').addEventListener('click', function () {
let marg = table.querySelectorAll('td.cell__active');
if (marg.length > 1) {
for (let i = 0; i < marg.length; i++) {
i == 0 ? marg[i].setAttribute('colspan', marg.length, 0) : marg[i].remove();
}
}
});
</script>
Может кто накинет идею, как мне выделить ячейки. Тестово поставил - мышкой поводить добавляет класс и по классу объединяет. Но это неправильно. |
Цитата:
|
Цитата:
Проблема в том, что у меня нет идеи как выделять ячейки, при этом нужно выделять прямоугольной областью не вылазя за пределы tbody, thead, tfooter. При объединении по горизонтали моё решение подходит, а вот в высоту пока только мысли проставить атрибуты с номерами строк или может по родителю ячеек как то можно. Но я не могу выделить ячейки, поэтому в высоту пока не развиваю идею. |
Цитата:
Цитата:
Откройте любое ПО, которое может создавать таблицы, объединять ячейки, тот же Word. Сохраните код как html и посмотрите структуру таблицы с объединенными ячейками, в особенности если в строке есть объединение в столбце. Это даст понимание того, что при объединении ячеек столбца не все так просто будет как с объединением в строке. |
выделятор блоков и обьединение ячеек
MC-XOBAHCK,
макет, обьединение ячеек(mergeTd) расчитано на первый клик!!!(требует доработки). выделить ячейки и нажать кнопку
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
table{
height: 250px;
width: 250px;
border-collapse: separate;
}
td{
border: 1px #0000CD solid;
background-color: #800080;
}
td.sel{
opacity:.6;
}
#line{
position:absolute;
width:0px;
height:0px;
background:rgba(0,90,255,0.25);
border:1px solid rgba(0,114,255,0.5);
box-sizing:border-box;
}
</style>
<script>
window.addEventListener("DOMContentLoaded", function() {
var target = document.createElement("div"),
x, y;
target.id = "line";
document.addEventListener("mousedown", function(e) {
if (e.which > 1) return;
x = e.pageX;
y = e.pageY;
document.body.appendChild(target);
selectBlock();
document.addEventListener("mousemove", move, false);
return false
}, false);
function move(e) {
e.preventDefault();
target.style.width = Math.abs(e.pageX - x) + "px";
target.style.height = Math.abs(e.pageY - y) + "px";
target.style.left = (e.pageX < x ? e.pageX : x) + "px";
target.style.top =
(e.pageY < y ? e.pageY : y) + "px";
selectBlock(true)
}
document.addEventListener("mouseup", function() {
target.style.width = "0px";
target.style.height = "0px";
document.removeEventListener("mousemove", move);
target.parentNode && document.body.removeChild(target)
});
function collisionDetection(x1, y1, w1, h1, x2, y2, w2, h2) {
return x1 < x2 + w2 && y1 < y2 + h2 && x1 + w1 > x2 && y1 + h1 > y2
}
function coordinate(el) {
var pos = el.getBoundingClientRect(),
top = pos.top,
left = pos.left,
right = pos.right,
bottom = pos.bottom,
height = bottom - top,
width = right - left;
return [left,
top, width, height
]
}
function selectBlock(add) {
[].forEach.call(document.querySelectorAll("td"), function(el) {
var data = coordinate(el).concat(coordinate(target)),
modify = add && collisionDetection.apply(null, data) ? "add" : "remove";
el.classList[modify]("sel")
})
}
function mergeTd(event) {
var tds = document.querySelectorAll("td.sel"),
len = tds.length,
colspan = 1,
parent;
if (len) {
[].forEach.call(tds, function(el, i) {
if (i) {
var elParent = el.parentNode;
parent == elParent && colspan++;
elParent.removeChild(el)
} else parent = el.parentNode
});
tds[0].colSpan = colspan;
tds[0].rowSpan = len / colspan
}
}
document.querySelector(".merge").addEventListener("mousedown", mergeTd)
});
</script>
</head>
<body>
<table>
<tbody>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
</tbody>
</table>
<input name="" type="button" value="go" class="merge">
</body>
</html>
|
рони, Спасибо вам!
Вижу выделение ячеек происходит так как нужно, и вижу баг, что вы указали как требует доработки. Я с утра приболел, вот начинаю приходить в себя и разбирать код. Я код понимаю, но не весь. Если можно - есть вопросы. В строке 33 создаётся элемент - createElement. Это прямоугольник области выделения мышью? 37 строка if (e.which > 1) return; - я правильно понял - это условие останавливает выполнение функции если код клавиши > 1 ? То есть вместе с событием mousedown это и есть нажатая левая кнопка мыши. |
MC-XOBAHCK,
да и да :) |
MC-XOBAHCK,
Цитата:
|
Цитата:
Получается, что выделение ячеек вы реализовали, а нужно доработать последнюю функцию - вот эту:
function mergeTd(event) {
var tds = document.querySelectorAll("td.sel"),
len = tds.length,
colspan = 1,
parent;
if (len) {
[].forEach.call(tds, function (el, i) {
if (i) {
var elParent = el.parentNode;
parent == elParent && colspan++;
elParent.removeChild(el)
} else parent = el.parentNode
});
tds[0].colSpan = colspan;
tds[0].rowSpan = len / colspan
}
}
document.querySelector("#margeTd").addEventListener("mousedown", mergeTd);
1. У функции принимающий параметр event можно убрать или лучше оставить? Я понимаю так, что он вообще не нужен и никакие события в функции не отслеживаются. Работа происходит только с массивом выделенных ячеек. 2. Последние две строчки функции tds[0].colSpan = colspan; tds[0].rowSpan = len / colspan Это тоже самое что:
tds[0].setAttribute('colspan', colspan, 0);
tds[0].setAttribute('rowspan', len / colspan, 0);
? 3. Идея как считать высоту и ширину для объединённой ячейки у меня появилась. Буду пробовать. Нужно немного посидеть поисследовать. Думаю у меня должно получиться, основная логика всё таки уже написана. 4. А вот что мне сложно будет доработать, это сделать правильное выделение. Вот только что обнаружил возможность вот такого выделения ячеек:
<style>table, th, td{min-width:50px;min-height:100px;border:solid 1px #ccc} th, td{min-width:50px;min-height:15px}</style>
<table>
<tr><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td rowspan="2" style="background:red"></td></tr>
<tr><td></td><td style="background:red"></td></tr>
</table>
вот же блин... |
MC-XOBAHCK,
да 1.можно убрать 2.свойство и атрибут, в данном случае изменение свойства равно назначению атрибута, такое не всегда, например свойство value можно изменить, атрибут останется прежним. подробнее тут https://learn.javascript.ru/attribut...nachenie-value 3. удачи!!! 4. не знаю, выбор за вами, смотря какой нужен результат. |
| Часовой пояс GMT +3, время: 02:03. |