开发者社区> 问答> 正文

在 table 中给 td 设定 position:absolute 出现的 rowspan 失效的问题

screenshot
在这个表格中,表头一1 和 表头二2 这两列是固定的,目前想到的解决方案是,使用 position:absolute; 但是,这个绝对定位不能相对于 table 来定位,因为这样无法实现冻结这两列的效果。

我们只能通过它相对于屏幕的最左来固定第一列,同时通过 JS 来计算出第二列相对于屏幕的最左的距离,并给这列加上一个属性 offsetLeft;

随后给第三列(这是不需要固定的列)一个 paddingLeft 值来防止它被因为设置 position:absolute 而脱离文档流的固定列所覆盖。

下面是具体的代码:

<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        .table{width: 1000px;overflow-x: scroll;margin:auto;}
        table{border:1px solid black;}
        table div{width: 200px;}
        td{width: 200px;text-align: center; border:1px solid blue; background-color:yellow;}
    </style>
</head>
<body>
<div class="table" id="fixedTable">
    <table>
        <thead>
            <tr>
                <td style="position: absolute; width:200px;"><div>表头1</div></td>
                <td style="position: absolute; width:200px;"><div>表头2</div></td>
                <td><div>表头3</div></td>
                <td><div>表头4</div></td>
                <td><div>表头5</div></td>
                <td><div>表头6</div></td>
                <td><div>表头7</div></td>
                <td><div>表头8</div></td>
            </tr>
        </thead>
        <tr>
            <td style="position: absolute; width:200px;">AAA</td>
            <td style="position: absolute; width:200px;">BBB</td>
            <td>CCC</td>
            <td>DDD</td>
            <td>EEE</td>
            <td>FFF</td>
            <td>GGG</td>
            <td>HHH</td>
        </tr>
    </table>
</div>
</body>

<script type="text/javascript">
    var trs = document.getElementById('fixedTable').getElementsByTagName('tr')
    for(var i = 0; i < trs.length; i++){
        //第 i 列
        var tr = trs[i]
        //计算所有固定列的总宽度
        var totalWidthOfFixedColumn = 0
        //计算列需要相对于屏幕左边的 offset
        var offsetLeft = document.getElementById('fixedTable').getElementsByTagName('td')[0].offsetLeft

        //第 i 列的所有单元格
        var tds = tr.getElementsByTagName('td')
        for(var j = 0; j <= 2 && j < tds.length; j++){
            //第 i 列的第 j 个单元格
            var td = tds[j]
            //当前单元格宽度
            var currentTdWidth = parseInt(td.style.width.slice(0, -2))
            if(j === 2){
                //当 j == 2 时,说明已经处理完所有固定的列,需要给这一列一个 paddingLeft 防止因为 position:absolute 脱离文档流
                //导致的该列被其他固定列锁覆盖
                td.style.paddingLeft = totalWidthOfFixedColumn + 'px';
                continue
            }

            totalWidthOfFixedColumn += currentTdWidth
            td.style.left = offsetLeft + 'px'
            try{
                offsetLeft += currentTdWidth
            }catch(e){
                console.error(e)
            }
        }
    }
</script>
</html>

具体效果如下:
screenshot
随后,我将表头更改为如下:

        <thead>
            <tr>
                <td style="position: absolute; width:200px;" rowspan="2"><div>表头一1</div></td>
                <td style="position: absolute; width:200px;" rowspan="2"><div>表头一2</div></td>
                <td><div>表头一3</div></td>
                <td><div>表头一4</div></td>
                <td><div>表头一5</div></td>
                <td><div>表头一6</div></td>
                <td><div>表头一7</div></td>
                <td><div>表头一8</div></td>
            </tr>
            <tr>
                <td><div>表头二1</div></td>
                <td><div>表头二2</div></td>
                <td><div>表头二3</div></td>
                <td><div>表头二4</div></td>
                <td><div>表头二5</div></td>
                <td><div>表头二6</div></td>
            </tr>
        </thead>

但是效果却成了如下形式:
screenshot
觉得应该还是因为前两列设置了 position:absolute 导致的元素脱离文档流引起的,但是不知道怎么解决,希望各位大神能不吝赐教。

展开
收起
杨冬芳 2016-06-12 09:56:24 5396 0
1 条回答
写回答
取消 提交回答
  • IT从业

    On a table I'd like the first 2 columns pinned in a fixed position, so I have to add position:absolute to the first 2

    tags. I want to merge the first row and the second row as well. So then I added rowspan="2" to both columns, unfortunately, rowspan isn't working on s with position:absolute.

    eg:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>td with position:absolute</title>
        <style type="text/css">
            .table{margin:auto; width: 1000px; overflow: visible;}
            td{text-align: center; background-color: yellow; border:1px solid black;}
            table div{width:200px;}
        </style>
    </head>
    <body>
        <div class="table">
            <table>
                <thead>
                <tr>
                    <!-- You can remove the attribute "position:absolute" to see the result -->
                    <td style="position:absolute;" rowspan="2"><div>Table head Row 1</div></td>
                    <td><div>Table head Row 2</div></td>
                    <td><div>Table head Row 3</div></td>
                    <td><div>Table head Row 4</div></td>
                    <td><div>Table head Row 5</div></td>
                    <td><div>Table head Row 6</div></td>
                </tr>
                <tr>
                    <td><div>Table head Row 2</div></td>
                    <td><div>Table head Row 3</div></td>
                    <td><div>Table head Row 4</div></td>
                    <td><div>Table head Row 5</div></td>
                    <td><div>Table head Row 6</div></td>
                </tr>
                </thead>
            </table>
        </div>
    </body>
    </html>

    Screenshot: Result with position:absolute

    Plunker: position: absolute applied

    Screenshot: Result without position:absolute

    Plunker: position: absolute not applied

    2019-07-17 19:33:14
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Transforming the data center 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载