如何通过JavaScript清除SVG元素中的文本

时间:2019-04-15 03:04:28

标签: javascript svg

我正在写一些嵌入SVG文件中的JavaScript。此代码使一些多行工具提示在鼠标悬停在圆圈上时出现。除了一件事,代码在这一点上运行良好。当他们第一次将鼠标悬停在圆圈上时,文本会正确显示,但是下次他们将鼠标悬停在圆圈上时,相同的文本会附加到第一个文本上,从而使文本出现两次。我一直在试图找出如何在我的mouseoff函数中清除此问题,但是我很困惑。

更新:我也添加了SVG,所以这是完整文件。

<?xml version="1.0" encoding="utf-8"?>
<svg id="oidc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 422 339.2" overflow="visible">
    <style type="text/css">
    .st13 {
        fill:#d9489b
    }
    .st13:hover {
        cursor:help;
        fill:#E66E31;
    }
    #tooltip {
          dominant-baseline: hanging;
          font-size: 8px;
      }
  </style>
    <g>
        <g>
            <circle class="st13" cx="47.8" cy="69.2" r="6" data-tooltip-text="I am some fairly long text." data-width="150" />
            <circle class="st13" cx="321.2" cy="65.7" r="6" data-tooltip-text="I am some much much much much much much longer text, so long that I cannot discuss or itemize my exact length. It's looooong, very long. I can't say more." data-width="100" />
        </g>
        <g id="tooltip" visibility="hidden" transform="translate(87.9511512134412 127.90914747977598)">
            <rect x="2" y="2" width="52.90066909790039" height="24" fill="black" opacity="0.4" rx="2" ry="2"></rect>
            <rect width="52.90066909790039" height="24" fill="lightblue" rx="2" ry="2"></rect>
            <text x="4" y="6">A box</text>
        </g>
    </g>
  <script type="text/javascript"><![CDATA[

  (function () {
  var svg = document.getElementById("oidc");
  var tooltip = svg.getElementById("tooltip");
  var tooltipRects = tooltip.getElementsByTagName("rect");
  var triggers = svg.getElementsByClassName("st13");
  var tooltipText = tooltip.getElementsByTagName("text")[0];

  // Add listeners
  for (var i = 0; i < triggers.length; i++) {
    triggers[i].addEventListener("mouseover", showTooltip);
    triggers[i].addEventListener("mouseout", hideTooltip);
  }

  function showTooltip(evt) {

    var CTM = svg.getScreenCTM();
    var x = (evt.clientX - CTM.e + 6) / CTM.a;
    var tspanX = tooltipText.getAttributeNS(null, 'x');
    var y = (evt.clientY - CTM.f + 20) / CTM.d;
    tooltip.setAttributeNS(null, "transform", "translate(" + x + " " + y + ")");
    tooltip.setAttributeNS(null, "visibility", "visible");

    // Sets variable containing data-width as float
    var width = parseFloat(evt.target.getAttributeNS(null, "data-width"));

    // Replaces text Element string with string from st13
    tooltipText.firstChild.data = evt.target.getAttributeNS(null, "data-tooltip-text");

    // Convert string to array of words
    var words = tooltipText.firstChild.data.split(' ');

    // Clear original text
    tooltipText.firstChild.data = "";

    // Create empty tspan element
    var tspanElement = document.createElementNS("http://www.w3.org/2000/svg", "tspan");

    // Create text node containing a word
    var textNode = document.createTextNode(words[0]);

    // Add tspan element to DOM
    tspanElement.appendChild(textNode);

    // Add text to tspan element
    tooltipText.appendChild(tspanElement);

    for (var i = 1; i < words.length; i++) {
      var len = textNode.data.length;

      // Add next word
      tspanElement.firstChild.data += " " + words[i];

      if (tspanElement.getComputedTextLength() > width) {
        // Remove added word
        tspanElement.firstChild.data = tspanElement.firstChild.data.slice(0, len);

        // Create new tspan element
        tspanElement = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
        tspanElement.setAttributeNS(null, "x", tspanX);
        tspanElement.setAttributeNS(null, "dy", 10);
        textNode = document.createTextNode(words[i]);
        tspanElement.appendChild(textNode);
        tooltipText.appendChild(tspanElement);
      }
    }

    var bbox = tooltipText.getBBox();
    var textWidth = bbox.width;
    for (var i = 0; i < tooltipRects.length; i++) {
      tooltipRects[i].setAttributeNS(null, "width", textWidth + 8);
    }

    var textHeight = bbox.height;
    for (var i = 0; i < tooltipRects.length; i++) {
      tooltipRects[i].setAttributeNS(null, "height", textHeight + 8);
    }

  }

  function hideTooltip(evt) {
    tooltip.setAttributeNS(null, "visibility", "hidden");
  }
  })()


  ]]>
  </script>
</svg>

2 个答案:

答案 0 :(得分:0)

删除所有showTooltip函数要添加的tspan元素,并且不要清除firstChild.data。在下一个事件发生时,您将需要它。

function hideTooltip(evt) {
  console.clear();
  console.log('Mouse out');
  tooltip.setAttributeNS(null, "visibility", "hidden");
  // tooltipText.firstChild.data = "";
  tooltip.querySelector("text").innerHTML = "<tspan>";
  console.log(tooltip);
}

在任何情况下,显示工具提示似乎都不过分。无论您采用何种实现方式,您都可能想在纸上写下要点,准确地说明您希望在文档中发生什么以及何时发生。

这将使您的目标简单明了,因此您的代码将更短,更清晰。

答案 1 :(得分:0)

感谢您的提示。我终于设法清除了文本,如下所示:

  function hideTooltip(evt) {
    tooltip.setAttributeNS(null, "visibility", "hidden");
    var text = svg.getElementById('text');
    while(text.firstChild) {
      text.removeChild(text.firstChild);
    }
    var str = "A box";
    text.innerHTML = str;
  }