2012-06-10 3 views
11

У меня есть таблица HTML, содержащая как ROWSPAN, так и COLSPAN.Как я могу найти «визуальное местоположение» ячейки таблицы, используя jQuery?

Как я могу найти «визуальное местоположение» каждой ячейки с помощью jQuery?

Например, вот визуальное представление моей таблицы с каждой ячейкой, населенной с тем, что алгоритм «визуальное расположение» должен вернуться:
(Примечание: Я только действительно забочусь о клетках в <tbody> и ссылке на столбец может быть целое число, не буквенный символ, я сделал только это легко выделить проблему)

+--+--+--+--+--+ 
| |A |B |C |D | 
+--+--+--+--+--+ 
|1 |A1|B1 |D1| 
+--+--+--+--+ + 
|2 |A2 |C2| | 
+--+  +--+ + 
|3 |  |C3| | 
+--+--+--+--+--+ 
|4 |A4|B4|C4|D4| 
+--+--+--+--+--+ 
|XYZ   | 
+--+--+--+--+--+ 

Я попытался реализации первой, однако ссылка на ячейки C3 является неточной, как он не принимает учитывать ROWSPANS. Вторая ссылка может быть объединена в решение первой, но я не могу понять, как это сделать.

Я надеюсь использовать это как функция называется getCellLocation(cell), которая будет возвращать ассоциативный массив, который возвращает расположение что-то вроде этого:

function getCellLocation(cell) 
{ 
    var row_number = parseInt($(cell).parent().prevAll().length) + 1; 
    var col_number = 1; 
    $(cell).prevAll('td').each(function() { 
     col_number += $(this).attr('colspan') ? parseInt($(this).attr('colspan')) : 1; 
    }); 

    var location = new Array(); 
    location['row'] = row_number; 
    location['col'] = col_number; 
    location['index'] = $('td').index(cell) + 1; 
    return location; 
} 

$('table td').each(function(i){ 
    var cell = getCellLocation($(this)); 
    $(this).prepend('<span class="ref">R' + cell['row'] + ':C' + cell['col'] + ':D' + cell['index'] + '</span>'); 
}); 

Вот HTML таблицы примеров:

<table border="1" cellspacing="0"> 
    <thead> 
    <tr> 
     <th></th> 
     <th>A</th> 
     <th>B</th> 
     <th>C</th> 
     <th>D</th> 
    </tr> 
    </thead> 
    <tbody> 
    <tr> 
     <th>1</th> 
     <td>A1</td> 
     <td colspan="2">B1</td> 
     <td rowspan="3">D1</td> 
    </tr> 
    <tr> 
     <th>2</th> 
     <td rowspan="2" colspan="2">A2</td> 
     <td>C2</td> 
    </tr> 
    <tr> 
     <th>3</th> 
     <td>C3</td> 
    </tr> 
    <tr> 
     <th>4</th> 
     <td>A4</td> 
     <td>B4</td> 
     <td>C4</td> 
     <td>D4</td> 
    </tr> 
    </tbody> 
    <tfoot> 
    <tr> 
     <td colspan="5">XYZ</td> 
    </tr> 
    </tfoot> 
</table> 
<style> span { background-color: #ffc; margin-right: .5em;} </style> 

ответ

7

Вот мое решение:

function getCellLocation(cell) { 

    var cols = cell.closest("tr").children("td").index(cell); 
    var rows = cell.closest("tbody").children("tr").index(cell.closest("tr")); 
    var coltemp = cols; 
    var rowtemp = rows; 

    cell.prevAll("td").each(function() { 
     cols += ($(this).attr("colspan")) ? parseInt($(this).attr("colspan")) - 1 : 0; 
    }); 

    cell.parent("tr").prevAll("tr").each(function() { 
     //get row index for search cells 
     var rowindex = cell.closest("tbody").children("tr").index($(this)); 
     // assign the row to a variable for later use 
     var row = $(this); 
     row.children("td").each(function() { 
      // fetch all cells of this row 
      var colindex = row.children("td").index($(this)); 
      //check if this cell comes before our cell 
      if (cell.offset().left > $(this).offset().left) { 
       // check if it has both rowspan and colspan, because the single ones are handled before 
       var colspn = parseInt($(this).attr("colspan")); 
       var rowspn = parseInt($(this).attr("rowspan")); 
       if (colspn && rowspn) { 
        if(rowindex + rowspn > rows) 
        cols += colspn;      
       } 
       if(rowspn && rowindex + rowspn > rows) cols +=1; 
      } 

     }); 
    }); 

Я проверяю ячейки, у которых есть как столбцы, так и ряды, потому что остальные обрабатываются первыми пятью строками этого кода. Если в ячейках есть как rowspan, так и colspan, они должны выполнять другие ячейки, которые не находятся ниже OR в стороне от этой ячейки, поэтому мне нужно искать предыдущие ячейки ячейки для взаимодействия.

+0

и вот jsFiddle его: http://jsfiddle.net/bcnEW/ –

+0

Там, кажется, небольшая проблема или двойного учета в некоторых сценариях. Рассмотрим результат, когда он применяется к этой таблице (см. Ячейку Col3 Row2): [http://jsfiddle.net/tUn54/](http://jsfiddle.net/tUn54/) – Turgs

+0

обновил мой ответ и скрипку: http: //jsfiddle.net/bcnEW/1/ –

0

для этого конкретного макета (т.е. если ваша первая строка не имеет Colspan и более или менее равномерные границы ячеек), вы можете сделать это следующим образом:

function getCellLocation(cell) 
{ 
    var row_number = cell.parentNode.rowIndex; 
    var col_number = ""; 
    $(cell).parents('table').find('tr:first th').each(function() 
    { 
     if (cell.offsetLeft >= this.offsetLeft) 
     { 
      col_number = $(this).text(); 
     } 
     else return false; 
    }); 
    return col_number + row_number; 
} 

, если вы хотите изменить числовой столбец его

var col_number = 0; 
    ... 
if (cell.offsetLeft >= this.offsetLeft) 
{ 
    col_number++; 
} 
0

Здесь jQuery-решение, способное обрабатывать сложную структуру таблицы. Это решение использует Open Source WxT Table Parser: https://raw.github.com/wet-boew/wet-boew/master/src/js/dependencies/parserTable.js

Вы найдете документацию в Table Usability Concept Github Repository. Используйте документацию API, которая находится в разделе «Таблица Parser - выпуск WET 3.0».

Таблицы синтаксический анализ делается с помощью табличной разметки HTML и визуальных связей между ячейкой данных (TD) и ячейкой заголовка (й)

// Used to get the reference to the WxT table parser 
var _pe = window.pe || { 
    fn : {} 
}; 

// For each table elements 
$('table').each(function() { 

    var $tbl = $(this); 

    // Parse the table 
    _pe.fn.parsertable.parse($tbl); 

    // For each data cell 
    $('td', $tbl).each(function() { 

     var $td = $(this), 
      tblparser; 

     // Get the API structure as defined under "Table Parser - WET 3.0 release" (https://github.com/duboisp/Table-Usability-Concept/blob/master/API/td.md#table-parser---wet-30-release) 
     tblparser = $td.data().tblparser; 

     // Set the cell location (x, y) 
     $td.html(tblparser.row.rowpos + ', ' + tblparser.col.start); 


    }); 
}); 

Вы найдете рабочий пример здесь: http://jsfiddle.net/TVttA/

Приветствия

:-)

1
your solution  my proposed table design 
+--+--+--+--+--+  +--+--+--+--+--+ 
| |A |B |C |D |  | |A |B |C |D |  length 5 vs 5 
+--+--+--+--+--+  +--+--+--+--+--+ 
|1 |A1|B1 |D1|  |1 |A1|B1|//|D1| 
+--+--+--+--+ +  +--+--+--+--+--+ 
|2 |A2 |C2| |  |2 |A2|//|C2|//|  length 3 vs 5 
+--+  +--+ +  +--+--+--+--+--+ 
|3 |  |C3| |  |3 |//|//|C3|//| 
+--+--+--+--+--+  +--+--+--+--+--+ 
|4 |A4|B4|C4|D4|  |4 |A4|B4|C4|D4| 
+--+--+--+--+--+  +--+--+--+--+--+ 
|XYZ   |  |XY|//|//|//|//|  length 1 vs 5 
+--+--+--+--+--+  +--+--+--+--+--+ 
// cells labeled '//' above have this class 

td.stuffing { display: none; } 

Вы видите, что я там делал?

Это третий ряд, например:

<tr> 
    <th>2</th> 
    <td rowspan="2" colspan="2">A2</td> 
    <td class="stuffing"></td> 
    <td>C2</td> 
    <td class="stuffing"></td> 
</tr> 

Теперь функция для получения правильного индекса очень просто.

function getCellLocation(cell) { 
    return {row:cell.parentNode.rowIndex, cell:cell.cellIndex} 
} 


А вот бонус. Если бы вы получили доступ к скрытой ячейке, это автоматически переместится к правильному, которое охватывает скрытые.

function getSmartCell(table, row, col) { 
    var cell = table.rows[row].cells[col]; 
    if (cell.className.indexOf("stuffing") == -1) return cell; 

    // traverse Left 
    while ((row>0) && (col>0) && (cell.className.indexOf("stuffing") >= 0)) { 
     cell = table.rows[row].cells[--col]; 
    } 

    // roll back one cell if no colSpan is found 
    if (cell.colSpan == 1) cell = table.rows[row].cells[++col]; 

    // traverse Up 
    while ((row>0) && (col>0) && (cell.className.indexOf("stuffing") >= 0)) { 
     cell = table.rows[--row].cells[col]; 
    } 

    return cell; 
} 

Использование:

var tb = document.querySelector("table"); 
getCellLocation(getSmartCell(tb,3,2)); // {row: 2, cell: 1} 

ВНИМАНИЕ Я только что проверил код getSmartCell и возвращает неправильный результат, если два соседних трёх двоеточий. Мне нужно это исправить.

Вот пример https://jsfiddle.net/goua3m13/

+0

была преднамеренная причина, почему ячейки, где «сливаются», охватывают столбцы и строки в моем вопросе. Для прецедента это должно быть таким образом и не может использовать пустые ячейки и скрыть их. – Turgs

+1

@Turgs. Вы все еще можете использовать colspans и rowspans, а также использовать скрытые ячейки. – Qwerty

+0

Хорошая идея. Лучшая производительность, чем другие алгоритмы !!! –