如何实现鼠标悬停文本时同步改变SVG的悬停状态?
实现文本悬停联动对应SVG图形的悬停效果
方法一:CSS分组联动(无需JS)
把对应州的图形和文本放在同一个<g>容器中,通过父容器的hover状态同时控制内部的图形和文本样式,不管悬停在图形还是文本上,都会触发一致的样式变化。
修改后的HTML:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="us-map" preserveAspectRatio="xMinYMin meet" sodipodi:docname="NEVI.svg" inkscape:version="0.91 r13725" x="0px" y="0px" width="959px" height="593px" viewBox="174 100 959 593" enable-background="new 174 100 959 593" xml:space="preserve"> <sodipodi:namedview bordercolor="#666666" objecttolerance="10" pagecolor="#ffffff" borderopacity="1" gridtolerance="10" guidetolerance="10" inkscape:cx="509.19152" inkscape:cy="282.2353" inkscape:zoom="1.2137643" showgrid="false" id="namedview71" inkscape:current-layer="g5" inkscape:window-maximized="1" inkscape:window-y="-8" inkscape:window-x="-8" inkscape:pageopacity="0" inkscape:window-height="1017" inkscape:window-width="1920" inkscape:pageshadow="2"> </sodipodi:namedview> <!-- 将对应州的path和text放在同一个g容器中 --> <g data-state="HI" class="state-group"> <path fill="#4bb95a" d="M407.1,619.3l1.9-3.6l2.3-0.3l0.3,0.8l-2.1,3.1H407.1z M417.3,615.6l6.1,2.6l2.1-0.3l1.6-3.9 l-0.6-3.4l-4.2-0.5l-4,1.8L417.3,615.6z M448,625.6l3.7,5.5l2.4-0.3l1.1-0.5l1.5,1.3l3.7-0.2l1-1.5l-2.9-1.8l-1.9-3.7l-2.1-3.6 l-5.8,2.9L448,625.6z M468.2,634.5l1.3-1.9l4.7,1l0.6-0.5l6.1,0.6l-0.3,1.3l-2.6,1.5l-4.4-0.3L468.2,634.5z M473.5,639.7l1.9,3.9 l3.1-1.1l0.3-1.6l-1.6-2.1l-3.7-0.3V639.7z M480.5,638.5l2.3-2.9l4.7,2.4l4.4,1.1l4.4,2.7v1.9l-3.6,1.8l-4.8,1l-2.4-1.5 L480.5,638.5z M497.1,654.1l1.6-1.3l3.4,1.6l7.6,3.6l3.4,2.1l1.6,2.4l1.9,4.4l4,2.6l-0.3,1.3l-3.9,3.2l-4.2,1.5l-1.5-0.6l-3.1,1.8 l-2.4,3.2l-2.3,2.9l-1.8-0.2l-3.6-2.6l-0.3-4.5l0.6-2.4l-1.6-5.7l-2.1-1.8l-0.2-2.6l2.3-1l2.1-3.1l0.5-1l-1.6-1.8L497.1,654.1z"/> <text class="mp-label-out" font-size="12" y="350" x="-80" transform="matrix(1 0 0 1 517 302)" cursor="pointer">HI</text> </g> </svg>
修改后的CSS:
#us-map { display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; } /* 父容器hover时,内部的path和circle触发悬停样式 */ .state-group:hover path, .state-group:hover circle { stroke: #ffffff !important; stroke-width: 2px; stroke-linejoin: round; fill: #D3D3D3 !important; cursor: pointer; } .mp-label-out { fill: #4bb95a; } /* 可选:悬停时文本也变色,保持视觉统一 */ .state-group:hover .mp-label-out { fill: #000; }
这种方法纯CSS实现,逻辑简单,适合结构可控的场景。
方法二:JavaScript联动(适合无法修改HTML结构的场景)
如果不能调整HTML结构,就利用data-state属性关联文本和图形,通过监听鼠标事件切换样式类。
首先在CSS中定义通用悬停类:
#us-map { display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; } /* 定义悬停样式类 */ .hover-state { stroke: #ffffff !important; stroke-width: 2px; stroke-linejoin: round; fill: #D3D3D3 !important; cursor: pointer; } .mp-label-out { fill: #4bb95a; }
然后添加JavaScript代码:
// 获取所有文本标签 const stateLabels = document.querySelectorAll('.mp-label-out'); stateLabels.forEach(label => { // 获取对应的state值 const state = label.dataset.state; // 鼠标移入文本时,给对应图形添加悬停类 label.addEventListener('mouseover', () => { const targetPath = document.querySelector(`path[data-state="${state}"]`); if (targetPath) { targetPath.classList.add('hover-state'); } }); // 鼠标移出文本时,移除悬停类 label.addEventListener('mouseout', () => { const targetPath = document.querySelector(`path[data-state="${state}"]`); if (targetPath) { targetPath.classList.remove('hover-state'); } }); }); // 同时保持图形自身的悬停效果 const statePaths = document.querySelectorAll('path[data-state]'); statePaths.forEach(path => { path.addEventListener('mouseover', () => { path.classList.add('hover-state'); }); path.addEventListener('mouseout', () => { path.classList.remove('hover-state'); }); });
这种方法更灵活,适合HTML结构不能修改的情况,通过数据属性建立关联,确保文本和图形的联动。
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

