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

带rowspan/colspan合并单元格的表格过滤功能异常修复求助

问题:带合并单元格的表格过滤功能异常

我编写了一段HTML代码,期望通过filterTable()函数在输入框输入内容后对myTable表格执行过滤操作。例如输入“Rafael”时,需完整显示包含该关键词的行及其对应的所有合并单元格,隐藏其余不匹配的行。

原JavaScript代码

function filterTable() {
    var input = document.getElementById("searchInput");
    var filter = input.value;
    var table = document.getElementById("myTable");
    var rows = table.getElementsByTagName("tr");

    for (var i = 1; i < rows.length; i++) {
        rows[i].style.display = "none";
    }

    for (var i = 1; i < rows.length; i++) {
        var row = rows[i];
        var cells = row.getElementsByTagName("td");
        var rowMatchesFilter = false;

        for (var j = 0; j < cells.length; j++) {
            var cell = cells[j];
            var cellContent = cell.textContent;

            if (cellContent.indexOf(filter) > -1) {
                rowMatchesFilter = true;

                if (cell.getAttribute("rowspan")) {
                    var rowspan = parseInt(cell.getAttribute("rowspan"));
                    for (var k = 0; k < rowspan; k++) {
                        rows[i + k].style.display = "";
                    }
                } else {
                    row.style.display = "";
                }
                break;
            }
        }
        if (rowMatchesFilter) {
            row.style.display = "";
        }
    }
}

原HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Table Search</title>
    <style>
        table, th, td {
            border: 1px solid black;
            border-collapse: collapse;
            padding: 8px;
            width: 500px;
        }
    </style>
</head>
<body>

<h2>Information Table</h2>

<input type="text" id="searchInput" placeholder="Enter search text" oninput="filterTable()">

<table id="myTable">
    <thead>
        <tr>
            <th>Building</th>
            <th>Floor</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td rowspan="5">Building 1</td>
            <td rowspan="2">Floor 1</td>
            <td>Martin</td>
        </tr>
        <tr>
            <td>Cristiano</td>
        </tr>
        <tr>
            <td rowspan="3">Floor 2</td>
            <td>Karim</td>
        </tr>
        <tr>
            <td>Rafael</td>
        </tr>
        <tr>
            <td>Anna</td>
        </tr>
        <tr>
            <td>Building 2</td>
            <td>Floor 1</td>
            <td>Carlos</td>
        </tr>
    </tbody>
</table>
</body>
</html>

异常现象

输入“Rafael”后,过滤结果显示异常,仅展示:

BuildingFloorName
Rafael

预期效果

输入“Rafael”后,应完整显示对应行及合并单元格:

BuildingFloorName
Building 1Floor 2Rafael

修复方案

问题根源在于原逻辑只处理了当前匹配行的向下合并单元格,未处理向上的合并单元格(即当前行之前的单元格通过rowspan覆盖到当前行的情况),导致合并的表头内容无法显示。修复后的函数会同时追溯上下关联的合并单元格,确保布局完整。

修复后的filterTable()函数:

function filterTable() {
    const input = document.getElementById("searchInput");
    const filter = input.value.trim().toLowerCase();
    const table = document.getElementById("myTable");
    const rows = table.querySelectorAll("tbody tr");

    // 先隐藏所有行
    rows.forEach(row => row.style.display = "none");

    if (!filter) {
        // 输入为空时恢复显示所有行
        rows.forEach(row => row.style.display = "");
        return;
    }

    // 遍历所有行查找匹配项
    rows.forEach((row, rowIndex) => {
        const cells = row.querySelectorAll("td");
        let isMatch = false;

        // 检查当前行是否包含匹配内容
        cells.forEach(cell => {
            if (cell.textContent.trim().toLowerCase().includes(filter)) {
                isMatch = true;
            }
        });

        if (isMatch) {
            // 显示当前匹配行
            row.style.display = "";

            // 向上追溯:查找覆盖当前行的合并单元格所在行
            for (let i = 0; i < rowIndex; i++) {
                const prevRow = rows[i];
                prevRow.querySelectorAll("td").forEach(cell => {
                    const rowspan = parseInt(cell.getAttribute("rowspan")) || 1;
                    // 若之前的单元格rowspan覆盖到当前行,则显示该行
                    if (i + rowspan > rowIndex) {
                        prevRow.style.display = "";
                    }
                });
            }

            // 向下处理:显示当前单元格rowspan覆盖的后续行
            cells.forEach(cell => {
                const rowspan = parseInt(cell.getAttribute("rowspan")) || 1;
                if (rowspan > 1) {
                    for (let k = 1; k < rowspan; k++) {
                        rows[rowIndex + k]?.style.display = "";
                    }
                }
            });
        }
    });
}

修复说明

  1. 大小写兼容:将输入和单元格内容统一转为小写,实现不区分大小写的搜索,提升用户体验。
  2. 向上追溯合并单元格:找到匹配行后,遍历之前的所有行,检查是否有单元格通过rowspan覆盖当前行,确保合并的表头内容(如Building 1、Floor 2)能正常显示。
  3. 向下处理合并单元格:保留原逻辑中处理当前行单元格向下覆盖行的逻辑,确保合并单元格的所有关联行都被正确显示。
  4. 空输入处理:输入为空时直接恢复显示所有行,回到初始状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:38:12