Как получить предыдущую ячейку при rowspan?
Есть огромная таблица с данными, в которой частенько встречаются ячейки со атрибутами rowspan и colspan.
Дана определенная ячейка из таблицы и нужно найти содержимое ее соседей (слева и справа). Вот набросал мини-пример: http://jsfiddle.net/zj7RU/ Вот таблица. Задача получить содержимое соседа слева(ячейка с номером 0) от ячейки с номером 5. Как костыльный вариант использую следующую схему: 1) Создаю копию таблицы, где разворачиваю все colspan и rowspan (бью на ячейки с копированием содержимым) 2) Осуществляю переходы используя rowIndex и cellIndex Вариант рабочий, но жутко тормозит на больших таблицах. Хотелось бы без глобального перебора. |
Хитро.
Пока на ум приходит только построение виртуальной модели таблицы при загрузке и навигация уже по оной. |
а если nextSibling и previousSibling заюзать если известна требуемая (а она известна?)
|
Cepin,
1.Проставить в каждой ячейке свой индивидуальный класс 2. сделать первичный обход таблицы по строкам - добавить класс предыдущей ячейки к следущей(для добавления фиксируем ток первый класс в списке 3. Аналогичный обход сделать по столбцам и тоже добавлять только первый текущий класс в списке к последующей ячейке 4. При выборе данной ячейки -ищем все ячейки с классами прописанными в ней |
Как насчёт того, чтобы сохранять общее количество ячеек в строках, а неиспользуемым ячейкам ставить display: none
<table border=1 id="table" style="cursor: pointer;"> <tr> <td rowspan="3">0</td> <td>1</td> <td rowspan="3">2</td> <td>3</td> <td>4</td> </tr> <tr> <td style="display: none"></td> <td id="td">5</td> <td style="display: none"></td> <td>6</td> <td>7</td> </tr> <tr> <td style="display: none"></td> <td id="td">8</td> <td style="display: none"></td> <td>9</td> <td>0</td> </tr> </table> <script> window.onload = function (e) { var table = document.getElementById('table'); var len; var index; table.onclick = function(e) { e = e || event; var target = e.target || e.srcElement; if (target.parentNode.tagName == 'TR') { if (target.previousElementSibling == null) { alert('нет предыдущей ячейки') } else { index = target.parentNode.rowIndex; for (var i = index; i >= 0; i--) { if (target.previousElementSibling.style.display != 'none') { alert(target.previousElementSibling.innerHTML); break; } else { index--; target = table.rows[index].cells[target.cellIndex]; } } } } } } </script> |
К сожалению, но нет возможности как-то повлиять на вывод этой таблицы.
Вообщем, по совету Aetae решил делать не копию таблицу, а модель (в каждой ячейке хранит лишь запись о соотвествующих координатах первой таблицы) Что сделано для оптимизации: 1) Заранее определен максимальный rowspan (в моем случае это 3) 2) Сканировать теперь всю таблицу не обязательно. Стартовую строку для обработки можно начинать не с 0, а строка заданной ячейки - 5 (из-за максимального rowspan для избежания глюков). Правую и нижнюю сторону ограничиваем координатами известной ячейки + 1 Все это делает довольно сильно сокращает объем таблицы и дает высокую скорость обработки. Вроде даже работает, но чувствую, что могут быть камни в таком подходе. |
Цитата:
|
Вообще говоря задача типично решаемая в "Игре морской бой" тут где то было решение
|
<style> table, td {border: solid 1px; cursor: pointer} </style> <table id="table"> <tr> <td rowspan="3">0</td> <td>1</td> <td rowspan="3">2</td> <td colspan="2">3</td> <td>4</td> </tr> <tr> <td>5</td> <td rowspan="2">6</td> <td>7</td> <td>8</td> </tr> <tr> <td id="td">9</td> <td>10</td> <td>11</td> </tr> </table> <script> window.onload = function () {//onload begin var table = document.getElementById('table'); var coord, left, top, right, previous, next; var d = 5;//здесь можно уточнить var p, n; table.onclick = function(e) {//onclick begin e = e || event; var target = e.target || e.srcElement; if (target.parentNode.tagName == 'TR') {//if begin coord = target.getBoundingClientRect(); left = coord.left + 1; top = coord.top + 1; right = coord.right; previous = document.elementFromPoint(left - d, top); next = document.elementFromPoint(right + d, top); if (previous.parentNode.tagName == 'TR') { p = previous.innerHTML; } else { p = 'нет'; } if (next.parentNode.tagName == 'TR') { n = next.innerHTML; } else { n = 'нет'; } alert('предыдущий: ' + p + '\nследующий: ' + n) }//if end }//onclick end }//onload end </script> |
bes,
Плюс! - ток в универсальном варианте нун искать все элементы по каждой из 4-x сторон: в порядке(обхода) прилегания и Учитываешь ли - что эл-т может быть одновременно и rowspan и colspan ? (*Ксать скрипт весьма востребованный в бугалтерских расчетах - если exel таблы переносят в брауз, Его бы добить и вылизать |
Цитата:
Цитата:
|
Так и знал что кто-нить использует пиксельный метод.
Главный минус его в том, что малейшее изменение стиля - и он перестанет работать. |
Цитата:
|
Цитата:
<style> table, td {border: solid 1px; cursor: pointer} *!* table{border-spacing:6px}*/!* </style> <table id="table"> <tr> <td rowspan="3">0</td> <td>1</td> <td rowspan="3">2</td> <td colspan="2">3</td> <td>4</td> </tr> <tr> <td>5</td> <td rowspan="2">6</td> <td>7</td> <td>8</td> </tr> <tr> <td id="td">9</td> <td>10</td> <td>11</td> </tr> </table> <script> window.onload = function () {//onload begin var table = document.getElementById('table'); var coord, left, top, right, previous, next; var d = 5;//здесь можно уточнить var p, n; table.onclick = function(e) {//onclick begin e = e || event; var target = e.target || e.srcElement; if (target.parentNode.tagName == 'TR') {//if begin coord = target.getBoundingClientRect(); left = coord.left + 1; top = coord.top + 1; right = coord.right; previous = document.elementFromPoint(left - d, top); next = document.elementFromPoint(right + d, top); if (previous.parentNode.tagName == 'TR') { p = previous.innerHTML; } else { p = 'нет'; } if (next.parentNode.tagName == 'TR') { n = next.innerHTML; } else { n = 'нет'; } alert('предыдущий: ' + p + '\nследующий: ' + n) }//if end }//onclick end }//onload end </script> |
Я поэтому и закомментировал строчку (var d = 5;//здесь можно уточнить), имея в виду, что можно более точно рассчитать расстояние между ячейками (задача чётко попасть в ячейку, а не в промежуток между ними).
Допустим рассчитали, какие могут быть ещё варианты изменения стилей, чтобы скрипт потерял работоспособность? |
Ну пиксельный имхо не АЙС, суть в том что Фактически, еще раз Фактичекси - все пикселы и координаты определяются столбцом и строкой якобы встроенных в ячейку - одного или нескольких ячеек с colspan и rowspan =1, поэтому на пикселы разменивацо смысла нет
координаты "Писксела" в таблице - есть координаты ячейки(столбец-строка) с размерами colspan-rowspan 1Х1 вписанного реального(если элемент соответствует 1Х1) или псевдо(если размеры больше) подобного элемента И ширина - высота тоже в ячейках |
Ячейки таблицы не такие уж и маленькие, чтобы в них не попасть.
Чем меньше размер ячейки, тем выше вероятность промаха, но вероятность того, что будут работать с чрезвычайно уменьшенной таблицей мала (естественно, данный способ не подходит для скрытых таблиц). Если нужна абсолютная точность, можно подстраховаться, попиксельно (в смысле, увеличивая или уменьшая координату на 1) пройдя в цикле от самой ячейки до первой встретившейся (если такая есть) в нужном направлении. Проще решения для произвольной таблицы с ячейками с rowspan и colspan, на мой взгляд, пока не видно. |
bes,
я имхо не про размер - Я про идеологию Ну взять подложить под текущую таблицу такую же, но чисто с одно ячеистой структурой |
Цитата:
PS: я выше также предлагал выровнять структуру, что, кстати, наверное реально (пройтись по таблице и добавить недостающие ячейки с display: none). А, кстати, это наверное неплохое решение, только проходя по таблице, добавлять не просто ячейки с display: none, а также и с соответствующим содержимым (тогда расчёт вообще простой). |
bes,
Ну моё предложение прозвучало - проставить каждой ячейке индивидуальный класс затем обойти и добавить классы соседских, добавляем только первый класс в списке, тады у нас классы всех сторон в атрибуте класс и поиск соседних перебором всех классов в текущей ячейке, нaчиная со второго в списке Создание уникального класса элемента - номер строки + через букву номер столбца Выяснить отсутствие соседей, зная класс текущего элемента и общее колво строк и столбцов и его соllspan, rowspan - тоже сложностей не представляет |
Цитата:
|
Цитата:
Яж написал как классы проставить - номер строки ячейки и номер столбца... (Да забить - просто по себе заю - что тяжело перейти к иным идеям , при наличии достаточно удачных своих Твоя реализация тоже интересна |
Цитата:
|
<!doctype html> <style> table, td {border: solid 1px; cursor: pointer} </style> <table id="table"> <tr> <td rowspan="3">0</td> <td>1</td> <td>16</td> <td rowspan="2" colspan="2">2</td> <td colspan="3">3</td> <td>4</td> </tr> <tr> <td colspan="2">5</td> <td rowspan="2">6</td> <td colspan="2">7</td> <td>17</td> </tr> <tr> <td>9</td> <td>10</td> <td>11</td> <td>12</td> <td>14</td> <td>15</td> <td>18</td> </tr> </table> <script> window.onload = function () {//onload begin var table = document.getElementById('table'); var len = table.rows.length; var row, cell, td, colspan, rowspan, m; for (var i = 0; i < len; i++) { row = table.rows[i]; for (var j = 0; j < row.children.length; j++) { cell = row.children[j]; colspan = cell.getAttribute('colspan'); if (colspan) { for (var k = 1; k < colspan; k++) { td = row.insertCell(j + k); td.innerHTML = cell.innerHTML; td.style.display = 'none'; } j += colspan - 1; } } } for (var i = 0; i < len; i++) { row = table.rows[i]; for (var j = 0; j < row.children.length; j++) { cell = row.children[j]; rowspan = cell.getAttribute('rowspan'); if (rowspan) { colspan = cell.getAttribute('colspan'); if (!colspan) { colspan = 1; } for (var m = 1; m < rowspan; m++) { for (var k = 0; k < colspan; k++) { td = table.rows[i+m].insertCell(j + k); td.innerHTML = cell.innerHTML; td.style.display = 'none'; } j += colspan - 1; } } } } table.onclick = function(e) {//onclick begin e = e || event; var target = e.target || e.srcElement; var previous, colspan, index, next, p, n; if (target.parentNode.tagName == 'TR') {//if begin previous = target.previousElementSibling; if (previous) { p = previous.innerHTML; } else { p = 'нет'; } colspan = target.getAttribute('colspan'); if (!colspan) { colspan = 1; } index = target.cellIndex + parseInt(colspan); next = target.parentNode.children[index]; if (next) { n = next.innerHTML; } else { n = 'нет'; } alert('предыдущий: ' + p + '\nследующий: ' + n); }//if end }//onclick end }//onload end </script> |
Гы -
Табло-навигатор по соседним ячейкам от выбранной *на выходе имеем массив из 4-х подмассивов указывающих на классы:слево, сверху,справо, снизу. все ячейки промаркированы классами вида: tr_Y_col_X <script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script> <style> table, td {border: solid 1px; cursor: pointer} </style> *Кликаем по первой таблице <br><br> <table id="table"> <!-- <tr> <td>01</td> <td>00</td> <td>01</td> <td>02</td> <td>03</td> <td>04</td> </tr>--> <tr> <td rowspan="3">00</td> <td>01</td> <td rowspan="3">02</td> <td colspan="2">03</td> <td>04</td> </tr> <tr> <td>05</td> <td rowspan="2">06</td> <td colspan="2">07</td> </tr> <tr> <td id="td">09</td> <td>10</td> <td>11</td> </tr> </table> <br><br> <div id=Ftore></div> <script> //Данные Функции лишь для раскраски: //(Можно их удалить,- удалив и 5 строк в основном теле скрипта. //=Раскраска= var NewColorTd = []; function setColor(){ var ColorsBank='00,11,22,33,44,55,66,77,88,99,aa,bb,cc,dd,ee,ff'; ColorsBank=ColorsBank.split(',') var ColorArray = [];var i=0; for(var r=15;r>=0;r--){ for(var g=0;g<=15;g++){ for(var b=0;b<=15;b++){ ColorArray[i]=ColorsBank[r]+''+ColorsBank[g]+''+ColorsBank[b]; i++; }}} var N = ColorArray.length; for(i=0; i<MaxTD; i++){ var ColorTD = Math.round(Math.random()*(N-1)); NewColorTd[i] = ColorArray[ColorTD]; } } </script> <script> var colsNext=0; var Maxrows = $("#table tr").length; var MaxTD = $("#table td").length; var MaxCols = 0; $("#table tr:first td").each(function(i) { MaxCols+=parseInt($(this).attr('colspan')); }); function setTable(a,b){ var i=0,j=0,str=""; var S="", TDst='<td>' var Tde='</td>\n',Ntd; for(j=0; j<a; j++){ var str='\n<tr>\n'+str; for (i=0; i<b; i++){ Ntd=b*j+i;str+=TDst+(Ntd+1)+Tde; } str+="</tr>\n";S+=str;str=""; } str='<table>'+S+'</table>'; return str; } var TabL=setTable(Maxrows,MaxCols); var CloneTbL = $("#Ftore") //.remove() //Временно Показал Для Дзен CloneTbL.append(TabL); //Clone Class in TD Double Table var TBL2 = CloneTbL.find("table"); function setAnalogTd (j,col,rowspan,colspan,set_Class) { for(x=j; x<j+rowspan; x++){ for(z=col; z<col+colspan; z++){ var TR=TBL2.find("tr").eq(x); var TD=TR.find("td").eq(z); TD.addClass("V "+set_Class); } } } //Calculate next column; var colsNext=0; function tstcolsNext(j){// var TR=TBL2.find("tr").eq(j);//alert(j) TR.find("td").each(function(v){ if(!$(this).hasClass("V")){/*alert(j+"Colonka="+v);*/colsNext=v;return false;} });return colsNext; } //Crawling cells and setting Class; setColor(); //Цвет - можно выкинуть var ColorTD=0; //Цвет - можно выкинуть $("#table tr").each(function(j) { $(this).find("td").each(function(i) { var color = "#"+NewColorTd[ColorTD]; //Цвет - можно выкинуть $(this).css({"background-color":color}); //Цвет - можно выкинуть if(!i&&!j)colsNext=0; if(j)tstcolsNext(j);//alert(colsNext); var col=colsNext; var colspan = parseInt($(this).attr('colspan')); colsNext = colsNext + colspan; if(colsNext>=MaxCols)colsNext=0; var rowspan = parseInt($(this).attr('rowspan')); var set_Class = 'tr_'+j+'_col_'+col $(this).addClass(set_Class); setAnalogTd (j,col,rowspan,colspan,set_Class) ColorTD++; //Цвет - можно выкинуть }); }); TBL2.find("td").removeClass("V"); </script><!-- Конец Setting-действий --> <script><!-- Тестирующая часть выбранной ячейки --> function extract_TR_andCol(klass) { var tr = parseInt(klass.replace(/tr_(\d+)[^\d].*/ig,'$1')); var col = parseInt(klass.replace(/.*?col_(\d+)(?:\s|$)/ig,'$1')); return [tr,col] } // =Обход периметра ячейки! var TBL1=$("#table tr"); // Тест Реального rowspan - если обе или более строки, // если обе или более строк (таблицы) подряд полностью заняты элементами с rowspan > 1; //===================================== function TstRealrowspan(klass,a,rowspan) { for(var i=1;i<rowspan; i++){ if(!TBL2.find("tr").eq(a[0]-1+i).find("td").eq(a[1]).hasClass(klass)){ rowspan=i-1; break; } } return rowspan; } function bypassing_perimeter(klass,colspan,rowspan) { var a=extract_TR_andCol(klass); if(rowspan>1){rowspan=TstRealrowspan(klass,a,rowspan)};// var Leftarray=[]; var Toparray=[]; var Rightarray=[]; var Bottomarray=[]; //Считываем все левые прилегающие элементы(сверху вниз) if(a[1]==0){ Leftarray=[]; } else { for(var i=0; i<rowspan; i++){ var elem=TBL2.find("tr").eq(a[0]+i).find("td").eq(a[1]-1).attr("class") if(i&&(Leftarray[i-1]!=elem))Leftarray.push(elem); if(i==0)Leftarray.push(elem); }} //Считываем верхние прилегающие элементы(слево-направо) if(a[0]==0){ Toparray=[]; } else { for(var i=0; i<colspan; i++){ var elem=TBL2.find("tr").eq(a[0]-1).find("td").eq(a[1]+i).attr("class") if(i&&(Toparray[i-1]!=elem))Toparray.push(elem); if(i==0)Toparray.push(elem); }} //Считываем все правые прилегающие элементы(сверху вниз) if((a[1]+colspan-1)==MaxCols-1){ Rightarray=[]; } else { for(var i=0; i<rowspan; i++){ var elem=TBL2.find("tr").eq(a[0]+i).find("td").eq(a[1]+1).attr("class") if(i&&(Rightarray[i-1]!=elem))Rightarray.push(elem); if(i==0)Rightarray.push(elem); }} //Считываем нижние прилегающие элементы(слево-направо) if((a[0]+rowspan-1)==Maxrows-1){ Bottomarray=[]; } else { for(var i=0; i<colspan; i++){ var elem=TBL2.find("tr").eq(a[0]+1).find("td").eq(a[1]+i).attr("class") if(i&&(Bottomarray[i-1]!=elem))Bottomarray.push(elem); if(i==0)Bottomarray.push(elem); }} return [Leftarray,Toparray,Rightarray,Bottomarray] } $("#table").find("td").each(function(i) { var color = $(this).css("background-color"); var klass = $(this).attr("class"); $("#Ftore table ."+klass).css({"background-color":color}); }) //=== Клик по ячейке ====// $("#table td").click(function() { var klass=$(this).attr('class'); var colspan=$(this).attr('colspan'); var rowspan=$(this).attr('rowspan'); var ALLArray = bypassing_perimeter(klass,colspan,rowspan) alert('Левые прилегающие элементы:\n' + ALLArray[0]+'\n\nВерхние прилегающие элементы:\n' + ALLArray[1]+'\n\nПравые прилегающие элементы:\n'+ALLArray[2]+'\n\nНижние прилегающие элементы:\n'+ALLArray[3]) }) </script> |
Код:
class is a reserved identifier |
Aetae,
CПС - (*В опере не кажет ошибку |
Цитата:
Куда менее затратно составить виртуальный массив содержащий только индексы соседей и обращаться к нему напрямую при запросе. |
Цитата:
Второе Чтобы составить индексы соседей нун знать начальный номер колонки для первой ячейки в строке(что для варианта перекрытия с rowspan лесенкой Скрин весьма и весьма - непросто - которую простейшей методой не определишь, есть еще камень: Если все ячейки в строке имеют rowspan более единицы -считыванием индекcа tr, то вроде как последущей строки tr вроде как и нет Так что считаю - кроме простановки id, а не класса - шустрее и универсальнее - не выполнить (хотя может я ошибаюсь - но пока доволен результатом проделанного |
:) На 1000 ячеек
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru" dir="ltr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251" /> <title>Табленавигатор</title> <script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script> </head> <body> <style id=Mystyle> table, td {border: solid 1px; cursor: pointer} </style> <script> function setTable(a,b){ var i=0,j=0,str=""; var S="", TDst='<td>' var Tde='</td>\n',Ntd; for(j=0; j<a; j++){ var str='\n<tr>\n'+str; for (i=0; i<b; i++){ Ntd=b*j+i;str+=TDst+(Ntd+1)+Tde; } str+="</tr>\n";S+=str;str=""; } str='<table id=table>'+S+'</table>'; return str; } var str=setTable(33,33) $("style#Mystyle").after(str) </script> <div id=Ftore></div> <script> //Данные Функции лишь для раскраски: //(Можно их удалить,- удалив и 5 строк в основном теле скрипта. //=Раскраска= var NewColorTd = []; function setColor(){ var ColorsBank='00,11,22,33,44,55,66,77,88,99,aa,bb,cc,dd,ee,ff'; ColorsBank=ColorsBank.split(',') var ColorArray = [];var i=0; for(var r=15;r>=0;r--){ for(var g=0;g<=15;g++){ for(var b=0;b<=15;b++){ ColorArray[i]=ColorsBank[r]+''+ColorsBank[g]+''+ColorsBank[b]; i++; }}} var N = ColorArray.length; for(i=0; i<MaxTD; i++){ var ColorTD = Math.round(Math.random()*(N-1)); NewColorTd[i] = ColorArray[ColorTD]; } } </script> <script> var colsNext=0; var Maxrows = $("#table tr").length; var MaxTD = $("#table td").length; var MaxCols = 0; $("#table tr:first td").each(function(i) { MaxCols=MaxCols+ parseInt($(this).attr('colspan')); }); function setTable(a,b){ var i=0,j=0,str=""; var S="", TDst='<td>' var Tde='</td>\n',Ntd; for(j=0; j<a; j++){ var str='\n<tr>\n'+str; for (i=0; i<b; i++){ Ntd=b*j+i;str+=TDst+(Ntd+1)+Tde; } str+="</tr>\n";S+=str;str=""; } str='<table>'+S+'</table>'; return str; } var TabL=setTable(Maxrows,MaxCols); var CloneTbL = $("#Ftore").remove() CloneTbL.append(TabL); //Clone Class in TD Double Table var TBL2 = CloneTbL.find("table"); function setAnalogTd (j,col,rowspan,colspan,set_Class) { for(x=j; x<j+rowspan; x++){ for(z=col; z<col+colspan; z++){ var TR=TBL2.find("tr").eq(x); var TD=TR.find("td").eq(z); TD.addClass("V "+set_Class); } } } //Calculate next column; var colsNext=0; function tstcolsNext(j){// var TR=TBL2.find("tr").eq(j);//alert(j) TR.find("td").each(function(v){ if(!$(this).hasClass("V")){/*alert(j+"Colonka="+v);*/colsNext=v;return false;} });return colsNext; } //Crawling cells and setting Class; setColor(); //Цвет - можно выкинуть var ColorTD=0; //Цвет - можно выкинуть $("#table tr").each(function(j) { $(this).find("td").each(function(i) { var color = "#"+NewColorTd[ColorTD]; //Цвет - можно выкинуть $(this).css({"background-color":color}); //Цвет - можно выкинуть if(!i&&!j)colsNext=0; if(j)tstcolsNext(j);//alert(colsNext); var col=colsNext; var colspan = parseInt($(this).attr('colspan')); colsNext = colsNext + colspan; if(colsNext>=MaxCols)colsNext=0; var rowspan = parseInt($(this).attr('rowspan')); var set_Class = 'tr_'+j+'_col_'+col $(this).addClass(set_Class); setAnalogTd (j,col,rowspan,colspan,set_Class) ColorTD++; //Цвет - можно выкинуть }); }); TBL2.find("td").removeClass("V"); </script><!-- Конец Setting-действий --> <script><!-- Тестирующая часть выбранной ячейки --> function extract_TR_andCol(klass) { var tr = parseInt(klass.replace(/tr_(\d+)[^\d].*/ig,'$1')); var col = parseInt(klass.replace(/.*?col_(\d+)(?:\s|$)/ig,'$1')); return [tr,col] } // =Обход периметра ячейки! var TBL1=$("#table tr"); // Тест Реального rowspan - если обе или более строки, // если обе или более строк (таблицы) подряд полностью заняты элементами с rowspan > 1; //===================================== function TstRealrowspan(klass,a,rowspan) { for(var i=1;i<rowspan; i++){ if(!TBL2.find("tr").eq(a[0]-1+i).find("td").eq(a[1]).hasClass(klass)){ rowspan=i-1; break; } } return rowspan; } function bypassing_perimeter(klass,colspan,rowspan) { var a=extract_TR_andCol(klass); if(rowspan>1){rowspan=TstRealrowspan(klass,a,rowspan)};// var Leftarray=[]; var Toparray=[]; var Rightarray=[]; var Bottomarray=[]; //Считываем все левые прилегающие элементы(сверху вниз) if(a[1]==0){ Leftarray=[]; } else { for(var i=0; i<rowspan; i++){ var elem=TBL2.find("tr").eq(a[0]+i).find("td").eq(a[1]-1).attr("class") if(i&&(Leftarray[i-1]!=elem))Leftarray.push(elem); if(i==0)Leftarray.push(elem); }} //Считываем верхние прилегающие элементы(слево-направо) if(a[0]==0){ Toparray=[]; } else { for(var i=0; i<colspan; i++){ var elem=TBL2.find("tr").eq(a[0]-1).find("td").eq(a[1]+i).attr("class") if(i&&(Toparray[i-1]!=elem))Toparray.push(elem); if(i==0)Toparray.push(elem); }} //Считываем все правые прилегающие элементы(сверху вниз) if((a[1]+colspan-1)==MaxCols-1){ Rightarray=[]; } else { for(var i=0; i<rowspan; i++){ var elem=TBL2.find("tr").eq(a[0]+i).find("td").eq(a[1]+1).attr("class") if(i&&(Rightarray[i-1]!=elem))Rightarray.push(elem); if(i==0)Rightarray.push(elem); }} //Считываем нижние прилегающие элементы(слево-направо) if((a[0]+rowspan-1)==Maxrows-1){ Bottomarray=[]; } else { for(var i=0; i<colspan; i++){ var elem=TBL2.find("tr").eq(a[0]+1).find("td").eq(a[1]+i).attr("class") if(i&&(Bottomarray[i-1]!=elem))Bottomarray.push(elem); if(i==0)Bottomarray.push(elem); }} return [Leftarray,Toparray,Rightarray,Bottomarray] } //=== Клик по ячейке ====// $("#table td").click(function() { var klass=$(this).attr('class'); var colspan=$(this).attr('colspan'); var rowspan=$(this).attr('rowspan'); var ALLArray = bypassing_perimeter(klass,colspan,rowspan) alert('Левые прилегающие элементы:\n' + ALLArray[0]+'\n\nВерхние прилегающие элементы:\n' + ALLArray[1]+'\n\nПравые прилегающие элементы:\n'+ALLArray[2]+'\n\nНижние прилегающие элементы:\n'+ALLArray[3]) }) </script> </body> </html> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru" dir="ltr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251" /> <title>Табленавигатор</title> <script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script> </head> <body> <style id=Mystyle> table, td {border: solid 1px; cursor: pointer} </style> <script> function setTable(a,b){ var i=0,j=0,str=""; var S="", TDst=function(){return '<td colspan="'+Math.floor(Math.random()*3+1)+'" rowspan="'+Math.floor(Math.random()*3+1)+'">'}; var Tde='</td>\n',Ntd; for(j=0; j<a; j++){ var str='\n<tr>\n'+str; for (i=0; i<b; i++){ Ntd=b*j+i;str+=TDst()+(Ntd+1)+Tde; } str+="</tr>\n";S+=str;str=""; } str='<table id=table>'+S+'</table>'; return str; } var str=setTable(33,33) $("style#Mystyle").after(str) </script> <div id=Ftore></div> <script> //Данные Функции лишь для раскраски: //(Можно их удалить,- удалив и 5 строк в основном теле скрипта. //=Раскраска= var NewColorTd = []; function setColor(){ var ColorsBank='00,11,22,33,44,55,66,77,88,99,aa,bb,cc,dd,ee,ff'; ColorsBank=ColorsBank.split(',') var ColorArray = [];var i=0; for(var r=15;r>=0;r--){ for(var g=0;g<=15;g++){ for(var b=0;b<=15;b++){ ColorArray[i]=ColorsBank[r]+''+ColorsBank[g]+''+ColorsBank[b]; i++; }}} var N = ColorArray.length; for(i=0; i<MaxTD; i++){ var ColorTD = Math.round(Math.random()*(N-1)); NewColorTd[i] = ColorArray[ColorTD]; } } </script> <script> var colsNext=0; var Maxrows = $("#table tr").length; var MaxTD = $("#table td").length; var MaxCols = 0; $("#table tr:first td").each(function(i) { MaxCols=MaxCols+ parseInt($(this).attr('colspan')); }); function setTable(a,b){ var i=0,j=0,str=""; var S="", TDst=function(){return '<td colspan="'+Math.floor(Math.random()*3+1)+'" rowspan="'+Math.floor(Math.random()*3+1)+'">'}; var Tde='</td>\n',Ntd; for(j=0; j<a; j++){ var str='\n<tr>\n'+str; for (i=0; i<b; i++){ Ntd=b*j+i;str+=TDst()+(Ntd+1)+Tde; } str+="</tr>\n";S+=str;str=""; } str='<table>'+S+'</table>'; return str; } var TabL=setTable(Maxrows,MaxCols); var CloneTbL = $("#Ftore").remove() CloneTbL.append(TabL); //Clone Class in TD Double Table var TBL2 = CloneTbL.find("table"); function setAnalogTd (j,col,rowspan,colspan,set_Class) { for(x=j; x<j+rowspan; x++){ for(z=col; z<col+colspan; z++){ var TR=TBL2.find("tr").eq(x); var TD=TR.find("td").eq(z); TD.addClass("V "+set_Class); } } } //Calculate next column; var colsNext=0; function tstcolsNext(j){// var TR=TBL2.find("tr").eq(j);//alert(j) TR.find("td").each(function(v){ if(!$(this).hasClass("V")){/*alert(j+"Colonka="+v);*/colsNext=v;return false;} });return colsNext; } //Crawling cells and setting Class; setColor(); //Цвет - можно выкинуть var ColorTD=0; //Цвет - можно выкинуть $("#table tr").each(function(j) { $(this).find("td").each(function(i) { var color = "#"+NewColorTd[ColorTD]; //Цвет - можно выкинуть $(this).css({"background-color":color}); //Цвет - можно выкинуть if(!i&&!j)colsNext=0; if(j)tstcolsNext(j);//alert(colsNext); var col=colsNext; var colspan = parseInt($(this).attr('colspan')); colsNext = colsNext + colspan; if(colsNext>=MaxCols)colsNext=0; var rowspan = parseInt($(this).attr('rowspan')); var set_Class = 'tr_'+j+'_col_'+col $(this).addClass(set_Class); setAnalogTd (j,col,rowspan,colspan,set_Class) ColorTD++; //Цвет - можно выкинуть }); }); TBL2.find("td").removeClass("V"); </script><!-- Конец Setting-действий --> <script><!-- Тестирующая часть выбранной ячейки --> function extract_TR_andCol(klass) { var tr = parseInt(klass.replace(/tr_(\d+)[^\d].*/ig,'$1')); var col = parseInt(klass.replace(/.*?col_(\d+)(?:\s|$)/ig,'$1')); return [tr,col] } // =Обход периметра ячейки! var TBL1=$("#table tr"); // Тест Реального rowspan - если обе или более строки, // если обе или более строк (таблицы) подряд полностью заняты элементами с rowspan > 1; //===================================== function TstRealrowspan(klass,a,rowspan) { for(var i=1;i<rowspan; i++){ if(!TBL2.find("tr").eq(a[0]-1+i).find("td").eq(a[1]).hasClass(klass)){ rowspan=i-1; break; } } return rowspan; } function bypassing_perimeter(klass,colspan,rowspan) { var a=extract_TR_andCol(klass); if(rowspan>1){rowspan=TstRealrowspan(klass,a,rowspan)};// var Leftarray=[]; var Toparray=[]; var Rightarray=[]; var Bottomarray=[]; //Считываем все левые прилегающие элементы(сверху вниз) if(a[1]==0){ Leftarray=[]; } else { for(var i=0; i<rowspan; i++){ var elem=TBL2.find("tr").eq(a[0]+i).find("td").eq(a[1]-1).attr("class") if(i&&(Leftarray[i-1]!=elem))Leftarray.push(elem); if(i==0)Leftarray.push(elem); }} //Считываем верхние прилегающие элементы(слево-направо) if(a[0]==0){ Toparray=[]; } else { for(var i=0; i<colspan; i++){ var elem=TBL2.find("tr").eq(a[0]-1).find("td").eq(a[1]+i).attr("class") if(i&&(Toparray[i-1]!=elem))Toparray.push(elem); if(i==0)Toparray.push(elem); }} //Считываем все правые прилегающие элементы(сверху вниз) if((a[1]+colspan-1)==MaxCols-1){ Rightarray=[]; } else { for(var i=0; i<rowspan; i++){ var elem=TBL2.find("tr").eq(a[0]+i).find("td").eq(a[1]+1).attr("class") if(i&&(Rightarray[i-1]!=elem))Rightarray.push(elem); if(i==0)Rightarray.push(elem); }} //Считываем нижние прилегающие элементы(слево-направо) if((a[0]+rowspan-1)==Maxrows-1){ Bottomarray=[]; } else { for(var i=0; i<colspan; i++){ var elem=TBL2.find("tr").eq(a[0]+1).find("td").eq(a[1]+i).attr("class") if(i&&(Bottomarray[i-1]!=elem))Bottomarray.push(elem); if(i==0)Bottomarray.push(elem); }} return [Leftarray,Toparray,Rightarray,Bottomarray] } //=== Клик по ячейке ====// $("#table td").click(function() { var klass=$(this).attr('class'); var colspan=$(this).attr('colspan'); var rowspan=$(this).attr('rowspan'); var ALLArray = bypassing_perimeter(klass,colspan,rowspan) alert('Левые прилегающие элементы:\n' + ALLArray[0]+'\n\nВерхние прилегающие элементы:\n' + ALLArray[1]+'\n\nПравые прилегающие элементы:\n'+ALLArray[2]+'\n\nНижние прилегающие элементы:\n'+ALLArray[3]) }) </script> </body> </html> Вот так, для полного испытания.)) |
Aetae,
:) А пояснения - можно ? - табла весьма кривая создана Воть ее вид в дебагере (и то Опера часть тегов Выправила: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru" dir="ltr"> <head></head> <body> <style id="Mystyle"></style> <table id="table"> <tbody> <tr></tr> <tr></tr> <tr></tr> <tr> <td colspan="0" rowspan="3" style="background-color: rgb(102, 51, 34)" class="tr_3_col_3"></td> <td colspan="0" rowspan="2" style="background-color: rgb(102, 255, 153)" class="tr_3_col_3"></td> <td colspan="1" rowspan="3" style="background-color: rgb(85, 136, 102)" class="tr_3_col_3"></td> <td colspan="2" rowspan="2" style="background-color: rgb(221, 204, 68)" class="tr_3_col_4"></td> <td colspan="3" rowspan="0" style="background-color: rgb(102, 0, 204)" class="tr_3_col_6"></td> <td colspan="2" rowspan="2" style="background-color: rgb(204, 221, 119)" class="tr_3_col_6"></td> <td colspan="1" rowspan="1" style="background-color: rgb(153, 153, 187)" class="tr_3_col_9"></td> <td colspan="3" rowspan="3" style="background-color: rgb(85, 102, 255)" class="tr_3_col_18"></td> <td colspan="1" rowspan="1" style="background-color: rgb(51, 187, 51)" class="tr_3_col_33"></td> <td colspan="1" rowspan="1" style="background-color: rgb(68, 238, 255)" class="tr_3_col_34"></td> <td colspan="0" rowspan="3" style="background-color: rgb(85, 204, 85)" class="tr_3_col_35"></td> <td colspan="3" rowspan="1" style="background-color: rgb(238, 34, 153)" class="tr_3_col_35"></td> <td colspan="2" rowspan="0" style="background-color: rgb(102, 34, 17)" class="tr_3_col_0"></td> <td colspan="1" rowspan="0" style="background-color: rgb(187, 102, 136)" class="tr_3_col_2"></td> <td colspan="2" rowspan="0" style="background-color: rgb(68, 255, 51)" class="tr_3_col_3"></td> <td colspan="0" rowspan="1" style="background-color: rgb(68, 255, 68)" class="tr_3_col_5"></td> <td colspan="0" rowspan="1" style="background-color: rgb(0, 102, 255)" class="tr_3_col_5"></td> <td colspan="2" rowspan="0" style="background-color: rgb(102, 255, 255)" class="tr_3_col_5"></td> <td colspan="1" rowspan="1" style="background-color: rgb(170, 238, 34)" class="tr_3_col_7"></td> <td colspan="0" rowspan="0" style="background-color: rgb(255, 187, 221)" class="tr_3_col_8"></td> <td colspan="2" rowspan="3" style="background-color: rgb(0, 119, 221)" class="tr_3_col_8"></td> <td colspan="0" rowspan="1" style="background-color: rgb(17, 153, 238)" class="tr_3_col_10"></td> <td colspan="2" rowspan="2" style="background-color: rgb(238, 255, 187)" class="tr_3_col_10"></td> <td colspan="3" rowspan="0" style="background-color: rgb(17, 17, 68)" class="tr_3_col_12"></td> <td colspan="0" rowspan="3" style="background-color: rgb(187, 0, 204)" class="tr_3_col_15"></td> <td colspan="1" rowspan="2" style="background-color: rgb(85, 85, 85)" class="tr_3_col_15"></td> <td colspan="2" rowspan="3" style="background-color: rgb(0, 170, 0)" class="tr_3_col_16"></td> <td colspan="0" rowspan="0" style="background-color: rgb(68, 255, 204)" class="tr_3_col_18"></td> <td colspan="3" rowspan="0" style="background-color: rgb(136, 17, 119)" class="tr_3_col_18"></td> <td colspan="2" rowspan="3" style="background-color: rgb(34, 238, 238)" class="tr_3_col_21"></td> <td colspan="3" rowspan="0" style="background-color: rgb(85, 51, 85)" class="tr_3_col_23"></td> <td colspan="1" rowspan="1" style="background-color: rgb(187, 136, 85)" class="tr_3_col_26"></td> <td colspan="3" rowspan="0" style="background-color: rgb(204, 238, 255)" class="tr_3_col_27"></td> </tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> <tr></tr> </tbody> </table> <script></script> <script></script> <script></script> <!-- Конец Setting-действий --> <script></script> </body> </html> |
Ксать могу отметить - что при увеличении colspan и rowspan скорость даже слегка растет
|
Пофиксил. Не идеально, конечно, но мне лень писать правильный код.
Суть в том что просто поменял TDst='<td>' на TDst=function(){return '<td colspan="'+Math.floor(Math.random()*3+1)+'" rowspan="'+Math.floor(Math.random()*3+1)+'">'}; И добавил вызов соответственно. Тупо рандом.) |
Aetae,
Да мну понял - бу время нарисую - хотя на деле есть готовый рандом таблица - на который тестил (но тут, в топике, тупо ограничение на символы |
:) Минималистическое решение тут http://javascript.ru/forum/offtopic/...tml#post189280 пост 13 от Raed!
|
Часовой пояс GMT +3, время: 19:55. |