鼠标悬停表格行时,如何同步修改行背景色与对应SVG路径填充色?
实现表格行与SVG路径的联动高亮效果
需求说明
网页会动态生成包含tableTr类的表格行,同时页面中有带pathClass类的SVG路径。需要实现:
- 鼠标悬停表格行时,该行背景色和对应SVG路径的填充色同步变化
- 鼠标移开后,两者恢复原状
- SVG路径自身被悬停时,填充色不变化,且仅支持表格行到SVG的单向交互(悬停SVG不会触发表格行高亮)
现有代码
HTML结构
<table> <tr> <td id="resultsCell"> <!-- 动态生成的表格 --> <table id="resultsTable"></table> </td> <td> <object id="map"> <svg id="mapSvg"> <path id="c000000" class="pathClass"></path> </svg> </object> </td> </tr> </table>
表格动态生成JS代码
var table = document.createElement("table"); table.setAttribute("class", "resultsTable"); table.setAttribute("id", "resultsTable"); for (var q = 0; q < 3143; q++){ var tr = document.createElement("tr"); tr.setAttribute("class", "tableTr"); var td1 = document.createElement('td'); td1.setAttribute("class", "tableTd"); var td2 = document.createElement('td'); td2.setAttribute("class", "tableTd"); if (q % 2){ td1.setAttribute("bgcolor", "#DEEAF6"); td2.setAttribute("bgcolor", "#DEEAF6"); } else { td1.setAttribute("bgcolor", "#FFFFFF"); td2.setAttribute("bgcolor", "#FFFFFF"); } if (q){ var text1 = document.createTextNode(results[q-1][0]); var text2 = document.createTextNode(results[q-1][1]); td1.appendChild(text1); td2.appendChild(text2); tr.appendChild(td1); tr.appendChild(td2); table.appendChild(tr); } else { var text1 = document.createTextNode("County"); var text2 = document.createTextNode("Deviation from Optimal"); td1.appendChild(text1); td2.appendChild(text2); tr.appendChild(td1); tr.appendChild(td2); table.appendChild(tr); } } document.getElementById("resultsCell").appendChild(table);
解决方案
步骤1:给表格行绑定对应SVG路径的ID
要让表格行和SVG路径建立关联,需在生成表格行时,把对应路径的ID存储到行的自定义属性中。假设results[q-1][2]是区县编码(对应SVG路径ID的前缀c+编码,比如c000000),修改表格生成代码的if (q)部分:
if (q){ var countyCode = results[q-1][2]; // 替换成实际存储编码的字段 var text1 = document.createTextNode(results[q-1][0]); var text2 = document.createTextNode(results[q-1][1]); td1.appendChild(text1); td2.appendChild(text2); // 给行添加自定义属性,存储对应SVG路径ID tr.dataset.pathId = "c" + countyCode; tr.appendChild(td1); tr.appendChild(td2); table.appendChild(tr); }
注:如果路径ID和区县名称直接关联,可改成
tr.dataset.pathId = "c" + results[q-1][0].replace(/\s/g, "")这类逻辑,核心是让表格行能精准找到对应SVG路径。
步骤2:添加交互逻辑
在表格生成完成后,绑定鼠标事件实现联动效果:
// 等待DOM加载完成后执行 document.addEventListener('DOMContentLoaded', function() { // 获取所有数据行(排除表头) const tableRows = document.querySelectorAll('.tableTr:not(:first-child)'); // 获取object标签内的SVG文档(因为路径在object内部,需先获取内部文档) const mapObject = document.getElementById('map'); let svgDoc; // 兼容不同浏览器获取SVG文档的方式 if (mapObject.contentDocument) { svgDoc = mapObject.contentDocument; } else if (mapObject.getSVGDocument) { svgDoc = mapObject.getSVGDocument(); } if (!svgDoc) return; // 给每个表格行绑定悬停/离开事件 tableRows.forEach(row => { const pathId = row.dataset.pathId; const pathElement = svgDoc.getElementById(pathId); if (!pathElement) return; // 存储原始状态 const originalBgColor = row.querySelector('td').style.backgroundColor || row.querySelector('td').getAttribute('bgcolor'); const originalFillColor = pathElement.getAttribute('fill') || '#cccccc'; // 默认填充色 // 鼠标悬停时高亮 row.addEventListener('mouseover', function() { // 修改表格行背景色 row.querySelectorAll('td').forEach(td => { td.style.backgroundColor = '#ffeb3b'; // 自定义高亮背景色 }); // 修改对应SVG路径填充色 pathElement.setAttribute('fill', '#ff5722'); // 自定义高亮填充色 }); // 鼠标离开时恢复原状 row.addEventListener('mouseout', function() { // 恢复表格行背景色 row.querySelectorAll('td').forEach(td => { td.style.backgroundColor = originalBgColor; }); // 恢复SVG路径填充色 pathElement.setAttribute('fill', originalFillColor); }); }); // 阻止SVG路径自身悬停时的填充变化 const svgPaths = svgDoc.querySelectorAll('.pathClass'); svgPaths.forEach(path => { path.addEventListener('mouseover', function(e) { e.stopPropagation(); // 阻止事件冒泡 // 强制保持原始填充色 const originalFill = path.getAttribute('fill'); path.setAttribute('fill', originalFill); }); }); });
步骤3:优化样式(可选)
把老旧的bgcolor属性替换成现代CSS样式,修改表格生成代码中的背景色设置部分:
if (q % 2){ td1.style.backgroundColor = "#DEEAF6"; td2.style.backgroundColor = "#DEEAF6"; } else { td1.style.backgroundColor = "#FFFFFF"; td2.style.backgroundColor = "#FFFFFF"; }
关键说明
- SVG路径的获取:由于路径在
<object>标签内部,必须通过contentDocument或getSVGDocument()获取内部SVG文档才能操作路径元素 - 单向交互实现:通过给SVG路径添加
mouseover事件并阻止冒泡,确保悬停路径时不会触发其他交互,同时强制保持原始填充色 - 状态存储:提前存储原始背景色和填充色,确保鼠标离开时能准确恢复初始状态
内容的提问来源于stack exchange,提问作者Squeaky Fox
相关产品推荐
相关产品推荐

