Таблица cellIndex и rowIndex с colspan/rowspan
Я использовал ответ, указанный в:
Как я могу найти "видимое местоположение" каждой ячейки таблицы? с помощью jQuery?
Но в этом случае это не работает: http://jsfiddle.net/TRr6C/9/
Обратите внимание, что 1,3 1,4 и 2,4 должны быть 1,4 1,5 и 2,5
Кто-нибудь видит, что не так?
Или есть ли лучшее решение для получения cellIndex и rowIndex из ячейки таблицы с учетом colspan и rowspan?
Вот код:
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;
}
}
});
});
return {
rows: rows,
cols: cols
};
}
Ответы
Ответ 1
Мое решение в форме плагина jQuery, поскольку я могу представить себе более чем одну цель иметь эту информацию. Его можно использовать как:
$("table tbody td").each(function(){
$(this).text( $(this).cellPos().top +","+ $(this).cellPos().left );
});
Позиция находится в форме { top: rows, left: cols }
.
При первом вызове таблица сканируется, а элементы TD
получают элементы data
с их кэшированной позицией. (Кэш можно перестроить, вызвав аргумент true
). Все последующие вызовы возвращают это кешированное значение.
Надеюсь, это поможет!
jsfiddle
Полный источник:
/* cellPos jQuery plugin
---------------------
Get visual position of cell in HTML table (or its block like thead).
Return value is object with "top" and "left" properties set to row and column index of top-left cell corner.
Example of use:
$("#myTable tbody td").each(function(){
$(this).text( $(this).cellPos().top +", "+ $(this).cellPos().left );
});
*/
(function($){
/* scan individual table and set "cellPos" data in the form { left: x-coord, top: y-coord } */
function scanTable( $table ) {
var m = [];
$table.children( "tr" ).each( function( y, row ) {
$( row ).children( "td, th" ).each( function( x, cell ) {
var $cell = $( cell ),
cspan = $cell.attr( "colspan" ) | 0,
rspan = $cell.attr( "rowspan" ) | 0,
tx, ty;
cspan = cspan ? cspan : 1;
rspan = rspan ? rspan : 1;
for( ; m[y] && m[y][x]; ++x ); //skip already occupied cells in current row
for( tx = x; tx < x + cspan; ++tx ) { //mark matrix elements occupied by current cell with true
for( ty = y; ty < y + rspan; ++ty ) {
if( !m[ty] ) { //fill missing rows
m[ty] = [];
}
m[ty][tx] = true;
}
}
var pos = { top: y, left: x };
$cell.data( "cellPos", pos );
} );
} );
};
/* plugin */
$.fn.cellPos = function( rescan ) {
var $cell = this.first(),
pos = $cell.data( "cellPos" );
if( !pos || rescan ) {
var $table = $cell.closest( "table, thead, tbody, tfoot" );
scanTable( $table );
}
pos = $cell.data( "cellPos" );
return pos;
}
})(jQuery);
Ответ 2
ванильная js версия @nrodic scanTable()
function scanTable(table)
{
var m = [];
for(var y=0; y<table.rows.length; y++)
{
var row = table.rows[y];
for(var x=0;x<row.cells.length;x++)
{
var cell = row.cells[x], xx = x, tx, ty;
for(; m[y] && m[y][xx]; ++xx); // skip already occupied cells in current row
for(tx = xx; tx < xx + cell.colSpan; ++tx) // mark matrix elements occupied by current cell with true
{
for(ty = y; ty < y + cell.rowSpan; ++ty)
{
if( !m[ty] ) m[ty] = []; // fill missing rows
m[ty][tx] = true;
}
}
// do here whatever you want with
// xx: the horizontal offset of the cell
// y: the vertical offset of the cell
}
}
};
Ответ 3
У меня улучшен ответ user652649, так что функция возвращает ячейку в соответствии с заданными координатами и не пропускает ячейки с col/rowspan, вот суть..., или просто код:
/**
* Returns the cell of the table by given (x;y) coordinates considering colSpan and rowSpan of the cells.
* @param {HTMLElement} table - HTML table
* @param {number} x - X position in table matrix
* @param {number} y - Y position in table matrix
* @returns {HTMLElement|null}
*/
var getTableCell = function (table, x, y) {
var m = [], row, cell, xx, tx, ty, xxx, yyy;
for(yyy = 0; yyy < table.rows.length; yyy++) {
row = table.rows[yyy];
for(xxx = 0; xxx < row.cells.length; xxx++) {
cell = row.cells[xxx];
xx = xxx;
for(; m[yyy] && m[yyy][xx]; ++xx) {}
for(tx = xx; tx < xx + cell.colSpan; ++tx) {
for(ty = yyy; ty < yyy + cell.rowSpan; ++ty) {
if (!m[ty])
m[ty] = [];
m[ty][tx] = true;
}
}
if (xx <= x && x < xx + cell.colSpan && yyy <= y && y < yyy + cell.rowSpan)
return cell;
}
}
return null;
};