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

动态SVG交互问题:JavaScript弹窗功能为何无法正常运行?

问题修复方案

核心问题

SVG属于XML命名空间,无法直接解析HTML的<div>标签,导致你定义的mypopup元素无法被浏览器正确渲染和获取,这是弹窗功能失效的根本原因。此外,原代码将事件绑定在父容器上,无法针对单个柱状条展示个性化内容。

修复后完整代码

<svg id="iamsvg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080">
  <defs>
  <style>
.zahlen {
  font-family:OpenSans-Regular, "Open Sans";
  font-size:50px;
  stroke:#000000;
  fill:#000000;
}

.balken {
  stroke-width:.5px;
  stroke:#5e5eee;
  fill:#5e5eee;
}

.balken:hover {
  stroke:#e70e7e;
  fill:#e70e7e;
}

.linien {
  stroke:#aeb6e5;
  stroke-miterlimit:10;
  fill:none;
}

#mypopup {
  width: 400px;
  padding: 20px;
  font-family: Arial, sans-serif;
  font-size: 10pt;
  background-color: white;
  border-radius: 6px;
  position: absolute;
  display: none;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  z-index: 9999;
}

#mypopup::before {
  content: "";
  width: 12px;
  height: 12px;
  transform: rotate(45deg);
  background-color: white;
  position: absolute;
  left: -6px;
  top: 68px;
}
      </style>
</defs><g>
    <line class="linien" x1="186.58" y1="1020.62" x2="1858.99" y2="1020.62"/>
    <line class="linien" x1="186.58" y1="1020.62" x2="186.58" y2="998.37"/></g>
  <g><g>
    <text class="zahlen" transform="translate(17.5 901.7)"><tspan x="0" y="0">10000</tspan></text>
    <text class="zahlen" transform="translate(17.5 753.37)"><tspan x="0" y="0">20000</tspan></text>
    <text class="zahlen" transform="translate(17.5 605.05)"><tspan x="0" y="0">30000</tspan></text>
    <text class="zahlen" transform="translate(17.5 456.72)"><tspan x="0" y="0">40000</tspan></text>
    <text class="zahlen" transform="translate(17.5 308.39)"><tspan x="0" y="0">50000</tspan></text>
    <text class="zahlen" transform="translate(17.5 160.07)"><tspan x="0" y="0">60000</tspan></text>
    </g>
    <line class="linien" x1="186.58" y1="1020.62" x2="186.58" y2="130.67"/><g>
    <line class="linien" x1="186.58" y1="1020.62" x2="228.39" y2="1020.62"/>
    <line class="linien" x1="186.58" y1="872.3" x2="1859.24" y2="872.3"/>
    <line class="linien" x1="186.58" y1="723.97" x2="1859.24" y2="723.97"/>
    <line class="linien" x1="186.58" y1="575.65" x2="1859.24" y2="575.65"/>
    <line class="linien" x1="186.58" y1="427.32" x2="1859.24" y2="427.32"/>
    <line class="linien" x1="186.58" y1="279" x2="1859.24" y2="279"/>
    <line class="linien" x1="186.58" y1="130.67" x2="1859.24" y2="130.67"/></g></g>
 <g id="myicon" pointer-events="all"> 
    <rect class="balken" x="201.21" y="572.25" width="75.26" height="448.37" data-title="柱状条1" data-desc="数值:40000,对应图表底部到顶部的高度"/>
    <rect class="balken" x="305.74" y="350.95" width="75.26" height="669.67" data-title="柱状条2" data-desc="数值:55000,为所有柱状条中最高"/>
    <rect class="balken" x="410.26" y="834" width="75.26" height="186.62" data-title="柱状条3" data-desc="数值:15000,属于较低水平"/>
    <rect class="balken" x="514.79" y="901.44" width="75.26" height="119.18" data-title="柱状条4" data-desc="数值:10000,接近最低刻度"/>
    <rect class="balken" x="619.31" y="982.58" width="75.26" height="38.05" data-title="柱状条5" data-desc="数值:3000,为所有柱状条中最低"/>
    <rect class="balken" x="723.84" y="919.9" width="75.26" height="100.73" data-title="柱状条6" data-desc="数值:9000,略高于最低刻度"/>
    <rect class="balken" x="828.37" y="766.11" width="75.26" height="254.51" data-title="柱状条7" data-desc="数值:20000,处于中等水平"/>
    <rect class="balken" x="932.89" y="951.99" width="75.26" height="68.63" data-title="柱状条8" data-desc="数值:6000,偏低水平"/>
    <rect class="balken" x="1037.42" y="603.16" width="75.26" height="417.46" data-title="柱状条9" data-desc="数值:38000,较高水平"/>
    <rect class="balken" x="1141.95" y="214.64" width="75.26" height="805.98" data-title="柱状条10" data-desc="数值:60000,达到最高刻度"/>
    <rect class="balken" x="1246.47" y="839.68" width="75.26" height="180.94" data-title="柱状条11" data-desc="数值:14500,较低水平"/>
    <rect class="balken" x="1351" y="973.31" width="75.26" height="47.32" data-title="柱状条12" data-desc="数值:4000,接近最低值"/>
    <rect class="balken" x="1455.52" y="852.61" width="75.26" height="168.01" data-title="柱状条13" data-desc="数值:13500,较低水平"/>
    <rect class="balken" x="1560.05" y="920.3" width="75.26" height="100.33" data-title="柱状条14" data-desc="数值:9000,略高于最低刻度"/>
    <rect class="balken" x="1664.58" y="859.22" width="75.26" height="161.41" data-title="柱状条15" data-desc="数值:13000,较低水平"/>
    <rect class="balken" x="1769.1" y="946.4" width="75.26" height="74.22" data-title="柱状条16" data-desc="数值:6500,偏低水平"/>
    </g>
    <script type="application/javascript">
      <![CDATA[
        // 动态创建弹窗并添加到HTML body
        function createPopup() {
          const popup = document.createElement('div');
          popup.id = 'mypopup';
          popup.innerHTML = `
            <h3 id="popup-title">Popup title</h3>
            <p id="popup-desc">Lorem ipsum dolor sit amet...</p>
          `;
          window.document.body.appendChild(popup);
          return popup;
        }

        let mypopup = window.document.getElementById('mypopup');
        if (!mypopup) {
          mypopup = createPopup();
        }

        const bars = document.querySelectorAll('.balken');
        
        // 为每个柱状条绑定悬停事件
        bars.forEach(bar => {
          bar.addEventListener('mouseover', showPopup);
          bar.addEventListener('mouseout', hidePopup);
        });

        function showPopup(evt) {
          const bar = evt.target;
          const barPos = bar.getBoundingClientRect();
          // 定位弹窗到柱状条右侧
          mypopup.style.left = (barPos.right + 20) + "px";
          mypopup.style.top = (window.scrollY + barPos.top - 60) + "px";
          // 替换弹窗内容为当前柱状条的自定义数据
          document.getElementById('popup-title').textContent = bar.dataset.title;
          document.getElementById('popup-desc').textContent = bar.dataset.desc;
          mypopup.style.display = "block";
        }

        function hidePopup(evt) {
          mypopup.style.display = "none";
        }
       ]]>
    </script> 
    </svg>

关键修改说明

  1. 移除SVG内的HTML标签:通过JavaScript动态创建弹窗元素并插入到浏览器的HTML body中,避开SVG无法解析HTML标签的限制。
  2. 单个柱状条绑定事件:将事件从父容器移到每个<rect>元素上,实现精准的悬停触发。
  3. 自定义数据属性:给每个柱状条添加data-title和data-desc属性,支持展示个性化的弹窗内容。
  4. 优化弹窗样式:增加阴影效果提升视觉层级,确保弹窗不会被SVG内容遮挡。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:01:59