14

我正在使用以下提供的答案:

如何使用 jQuery 找到每个表格单元格的“视觉位置”?

但在这种情况下似乎不起作用:http: //jsfiddle.net/TRr6C/9/

注意 1,3 1,4 和 2,4 应该是 1,4 1,5 和 2,5

有人看到有什么问题吗?

或者,考虑到 colspan 和 rowspan,有没有更好的解决方案从表格单元格中获取 cellIndex 和 rowIndex?

这是代码:

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

3 回答 3

19

我的解决方案是 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);
于 2012-11-17T01:33:08.070 回答
8

@nrodic 的 scanTable() 的 vanilla js 版本

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

        }
    }
};
于 2013-09-10T18:51:59.687 回答
6

我改进了 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;
};
于 2015-07-22T19:23:22.393 回答