Редактор и 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, время: 11:06. |