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

如何实现HTML表格中rowspan单元格的匹配对应部分高亮?

问题描述

我有如下结构的HTML表格:

表格初始样式:第一列是分组列(group),group1占3行,对应三个名称项:amy、test、amy2;group2占1行,对应名称项water。

<table>
 <thead>
 <tr>
 <th>no.</th>
 <th>name</th>
 </tr>
</thead>
 <tbody id="list">
<tr>
<td class="group" id="group_1" rowspan="3">1</td>
<td id="name_1">amy</td>
</tr>
<tr>
<td id="name_1">test</td>
</tr>
<tr>
<td id="name_1">amy2</td>
</tr>
<tr>
<td class="group" id="group_2">2</td>
<td id="name_2">water</td>
</tr>
</tbody>
</table>

我写了一段JavaScript实现搜索高亮功能:

function highlightKeyword() {
        let searchWord = document.getElementById("search").value.toLowerCase().replace(/\s+/g, '');
        let rows = document.getElementById("list").getElementsByTagName("tr");

        for (let i = 0; i < rows.length; i++) {
            let targetName = rows[i].getElementsByTagName("td")[rows[i].getElementsByTagName("td").length - 1];
            let name = targetName.textContent.toLowerCase().replace(/\s+/g, '');
            let targetCode = targetName['id'].substr(5);
            let groupTd = document.getElementById(`group_${targetCode}`);

            if (searchWord != "") { 
                if (name.includes(searchWord)) { 
                    rows[i].classList.add("highlighted-row");
                    groupTd.classList.add("highlighted-row");
                } else {
                    rows[i].classList.remove("highlighted-row");
                    groupTd.classList.remove("highlighted-row");
                }
            } else {
                rows[i].classList.remove("highlighted-row");
                groupTd.classList.remove("highlighted-row");
            }
        }
    }

现在的功能是搜索框匹配name列内容时,会高亮对应的行以及整个rowspan的分组单元格。但我想要的效果是:仅高亮rowspan分组单元格中与匹配行对应的区域,比如搜索“amy”时,amy和amy2所在的行高亮,同时分组列中这两行对应的区域也变黄,而test行对应的分组区域保持原样,不是整个分组单元格都变黄。

请问实现这个效果的最简方法是什么?

以下是完整可运行代码片段:

function highlightKeyword() {
        let searchWord = document.getElementById("search").value.toLowerCase().replace(/\s+/g, '');
        let rows = document.getElementById("list").getElementsByTagName("tr");

        for (let i = 0; i < rows.length; i++) {
            let targetName = rows[i].getElementsByTagName("td")[rows[i].getElementsByTagName("td").length - 1];
            let name = targetName.textContent.toLowerCase().replace(/\s+/g, '');
            let targetCode = targetName['id'].substr(5);
            let groupTd = document.getElementById(`group_${targetCode}`);

            if (searchWord != "") { 
                if (name.includes(searchWord)) {
                    rows[i].classList.add("highlighted-row");
                    groupTd.classList.add("highlighted-row");
                } else {
                    rows[i].classList.remove("highlighted-row");
                    groupTd.classList.remove("highlighted-row");
                }
            } else {
                rows[i].classList.remove("highlighted-row");
                groupTd.classList.remove("highlighted-row");
            }
        }
    }
.highlighted-row {
       background-color: yellow;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="form-control w-30" id="search" oninput="highlightKeyword()">
<table class="table table-sm table-bordered">
    <thead>
    <tr>
        <th>group.</th>
        <th>name</th>
    </tr>
    </thead>
    <tbody id="list">

    <tr>
        <td class="group" id="group_1" rowspan="3">1</td>
        <td id="name_1">amy</td>
    </tr>
    <tr>
        <td id="name_1">test</td>
    </tr>
    <tr>
        <td id="name_1">amy2</td>
    </tr>
    <tr>
        <td class="group" id="group_2">2</td>
        <td id="name_2">water</td>
    </tr>

    </tbody>
</table>

最简实现方法

核心思路是通过给无分组单元格的行添加占位td,让占位td和rowspan的分组单元格重叠,再通过行高亮控制占位td的背景,模拟出分组单元格局部高亮的效果,具体步骤如下:

1. 补全HTML表格结构

给每个没有分组单元格的<tr>添加一个空的<td class="group-placeholder"></td>,保证表格列数对齐:

<tbody id="list">
<tr>
    <td class="group" id="group_1" rowspan="3">1</td>
    <td id="name_1">amy</td>
</tr>
<tr>
    <td class="group-placeholder"></td>
    <td id="name_1">test</td>
</tr>
<tr>
    <td class="group-placeholder"></td>
    <td id="name_1">amy2</td>
</tr>
<tr>
    <td class="group" id="group_2">2</td>
    <td id="name_2">water</td>
</tr>
</tbody>

2. 调整CSS样式

让占位td和分组单元格重叠,默认隐藏边框,高亮时显示背景:

/* 单元格设为相对定位,方便层级控制 */
.table td {
    position: relative;
}
/* 去掉占位td的边框和内边距,和分组单元格完全重叠 */
.group-placeholder {
    border: none !important;
    padding: 0;
}
/* 高亮行时,给该行所有td加背景色 */
.highlighted-row td {
    background-color: yellow;
}
/* 分组单元格在底层,占位td在上层,确保高亮背景能显示出来 */
.group {
    z-index: 0;
}
.group-placeholder {
    z-index: 1;
}

3. 简化JavaScript逻辑

不再操作分组单元格的类,只需要根据搜索结果控制行的高亮状态:

function highlightKeyword() {
    let searchWord = document.getElementById("search").value.toLowerCase().replace(/\s+/g, '');
    let rows = document.getElementById("list").getElementsByTagName("tr");

    for (let row of rows) {
        let targetName = row.querySelector("td[id^='name_']");
        let name = targetName.textContent.toLowerCase().replace(/\s+/g, '');
        
        // 根据是否匹配切换高亮类
        row.classList.toggle("highlighted-row", searchWord && name.includes(searchWord));
    }
}

效果说明

当搜索匹配某一行时,该行的占位td会显示黄色背景,刚好覆盖分组单元格的对应区域,视觉上就像分组单元格的局部被高亮了;未匹配的行,占位td保持透明,不影响原有分组单元格的显示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:32:04