You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复jQuery DataTable列搜索时表头与tbody错位问题

jQuery DataTable横向滚动+列搜索时Tab切换输入框导致表头与tbody错位问题

我在用带列搜索和横向滚动的jQuery DataTable时,遇到一个问题:按下Tab键切换列搜索输入框时,表头会滚动但表格主体(tbody)不跟随滚动,出现错位。

问题截图

  • 错位效果:错位效果截图
  • 期望效果:期望效果截图

实现代码

CSS样式

.frm {
    /* padding-right: 75px; */
}

/* input {
    width: 250px!important;
} */
input[type='search'],
select[name="example_length"] {
    border: 1px solid #ced4da;
}

div.dataTables_wrapper {
    width: 100%;
    margin: 0 auto;
}

input[type='search']:focus {
    border: 1px solid #ced4da;
}

table.dataTable thead th {
    white-space: nowrap;
    text-transform: uppercase;
}

table td {
    word-wrap: break-word;
    max-width: 400px;
}

#example td {
    text-align: center;
}

#example .details {
    white-space: nowrap;
}

table.dataTable thead th,
table.dataTable thead td {
    border-bottom: none;
}

#example_length {
    padding-left: 14px;
}

@media (min-width: 992px) {
    .vw {
        width: 250px;
    }
}

div.dataTables_scrollBody {
    background: #f2f2f2 !important;
}

.dataTables_wrapper.no-footer .dataTables_scrollBody {
    border-bottom: none !important;
}

.dt-buttons {
    display: none;
}

.exp {
    padding-top: 25px;
    /* width: 50%; */
    /* margin-left: -45px; */
}

HTML与PHP部分

<table id="example" class="display table-bordered" style="width:100%;">
    <?php $questions = getallquestions($mysql_connectionLinkLocal); ?>
    <thead style="font-size:14px;background: #00a0e4;color: white;">
        <tr>
            <th>Badge Number</th>
            <th>Name</th>
            <th>Completion Time</th>
            <?php foreach ($questions as $row) {
                $qid = $row["id"];
                $question = $row["questions"]; ?>
                <?php if ($qid == 16) { ?>
                    <th class="" style=""><?php echo "Recommended Speed"; ?></th><?php } else { ?>
                    <th><?php echo $question; ?></th>
                <?php } ?>
            <?php } ?>
            <th style="">Category</th>
            <!-- <th style="display:none">Speed</th>  -->
        </tr>
    </thead>
    <tbody>
        <?php $getentry = getallentry($mysql_connectionLinkLocal, $badgenumber_rtr);
        foreach ($getentry as $row) {
            $lastmodified = $row["last_modified_date"];
            $name = $row["Name"];
            $shift = $row["shift"];
            $firstshiftreporting = $row["FirstShift"];
            $secondshiftreporting = $row["SecondShift"];
            $thirdshiftreporting = $row["ThirdShift"];
            $size = $row["size"];
            $process7mm = $row["7mmprocess"];
            $process9mm = $row["9mmprocess"];
            $machines7mm = $row["7mmFinPress"];
            $machines9mm = $row["9mmFinPress"];
            $slab7mm = $row["7mmSlab"];
            $slab9mm = $row["9mmSlab"];
            $slabs = $row["SLABS"];
            $spm = $row["SPM"];
            $reason = $row["reason"];
            $maxspm = $row["MAXSPM"];
            $downtime = $row["downtime"];
            $category = $row["category"];
            $speed = $row["speed"];
            // $btn = '<a href="index.php?viewanswer=1&answer='.$lastmodified.'&submission='.$subid.'"><button style="font-size:17px;background-color: #2a6a80;border-color: #2a6a80;"  class="btn btn-success" id="" type="button" name="submitviewentries" >View &nbsp;<i class="fas fa-eye"></i></button></a>';
            ?>
            <tr>
                <td class="details"><?php echo $row["BadgeNumber"] ?></td>
                <td class="details"><?php echo $name ?></td>
                <td class="details"><?php echo $row["last_modified_date"] ?></td>
                <td><?php echo $process7mm ?></td>
                <td><?php echo $size ?></td>
                <td><?php echo $shift ?></td>
                <td><?php echo $firstshiftreporting ?></td>
                <td><?php echo $secondshiftreporting ?></td>
                <td><?php echo $thirdshiftreporting ?></td>
                <td><?php echo $machines7mm ?></td>
                <!-- <td><?php echo $process9mm ?></td> -->
                <td><?php echo $machines9mm ?></td>
                <td><?php echo $slab7mm ?></td>
                <td><?php echo $slab9mm ?></td>
                <td><?php echo $slabs ?></td>
                <td><?php echo $spm ?></td>
                <td style=""><?php echo $speed ?></td>
                <td><?php echo $downtime ?></td>
                <td style="white-space: pre;"><?php echo $reason ?></td>
                <td style=""><?php echo $category ?></td>
                <!-- <td style="display:none;"><?php echo $speed ?></td> -->
            </tr>
        <?php } ?>
    </tbody>

JavaScript部分

$(document).ready(function () {
    var table=$('#example').DataTable({
        // stateSave: true
        "ordering": false,
        "retrieve": true,
        "fixedHeader": true,
        "scrollX": true,
        // "fixedColumns": {
        //    left: 1
        //  },
        scrollY: '600px',
        dom: 'lBfrtip',
        buttons: [
            {
                extend: 'excel',
                text: 'Export',
                title:'Aluminum Coil Production Tracking Entries',
                className: 'btn btn-primary',
                header: true,
                exportOptions: {
                    //columns: ':visible:not(.notexport)'
                    //columns: [':visible', 16,18,19 ]
                    columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
                }
            }
        ],
    });
    
    // Apply the search
    table.columns().every( function () {
        var that = this;
        $( 'input', this.header() ).on( 'keyup change', function () {
            if ( that.search() !== this.value ) {
                that.search( this.value )
                    .draw();
            }
        } );
    } );
} );

解决方案

这个问题根源是fixedHeader与scrollX结合时,Tab切换输入框触发表头滚动,但tbody容器未同步滚动位置。可以通过以下两种方式解决:

方式一:监听输入框焦点同步滚动

修改JavaScript代码,添加同步逻辑:

$(document).ready(function () {
    var table=$('#example').DataTable({
        // 原有配置不变
    });
    
    // 原有搜索逻辑不变
    
    // 新增:同步表头与tbody滚动位置
    table.columns().every(function() {
        $('input', this.header()).on('focus', function() {
            var scrollLeft = $('.dataTables_scrollHead').scrollLeft();
            $('.dataTables_scrollBody').scrollLeft(scrollLeft);
        });
    });

    // 监听Tab键切换时强制同步
    $(document).on('keydown', '.dataTables_scrollHead input', function(e) {
        if (e.key === 'Tab') {
            setTimeout(function() {
                var scrollLeft = $('.dataTables_scrollHead').scrollLeft();
                $('.dataTables_scrollBody').scrollLeft(scrollLeft);
            }, 10);
        }
    });
});

方式二:移除fixedHeader配置

如果不需要固定表头在顶部的功能,直接移除"fixedHeader": true配置,此时表头和tbody会处于同一个滚动容器内,自然不会出现错位问题。

内容的提问来源于stack exchange,提问作者REVATHI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 09:37:06