Подтвердить что ты не робот

Как я могу найти "визуальное местоположение" ячейки таблицы с помощью jQuery?

У меня есть таблица HTML, содержащая как ROWSPAN, так и COLSPAN.

Как я могу найти "визуальное местоположение" каждой ячейки с помощью 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>
4b9b3361

Ответ 1

Здесь мое решение:

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;
            }

        });
    });

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

Ответ 2

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, и он возвращает неверный результат, если есть два соседних файла rowspans. Мне нужно это исправить.

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

Ответ 3

для этого конкретного макета (т.е. если ваша первая строка не имеет 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++;
}

Ответ 4

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

Вы найдете документацию в Концепция GIF для удобства использования таблиц. Используйте документацию по API, находящуюся в разделе "Разбор таблицы Parser - WET 3.0".

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

// 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/

Приветствия

: -)