Как очистить текст из SVG-элемента с помощью JavaScript - PullRequest
1 голос
/ 15 апреля 2019

Я пишу некоторый JavaScript, который встроен в файл SVG.Этот код вызывает появление нескольких многострочных всплывающих подсказок при наведении курсора на круг.На данный момент код работает довольно хорошо, за исключением одной вещи.Текст отображается правильно, когда они впервые наводят курсор мыши на круг, но при следующем наведении курсора мыши тот же текст добавляется к первому, так что текст появляется дважды.Я пытался выяснить, как очистить это в моей функции 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 голосов
/ 16 апреля 2019

Спасибо за советы.Мне наконец удалось очистить текст следующим образом

  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;
  }
0 голосов
/ 15 апреля 2019

Удалите все элементы tspan, которые добавляет функция showTooltip, и не очищайте 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);
}

В любом случае, это похоже на перебор, чтобы показать всплывающую подсказку. Возможно, вы захотите записать на листе бумаги, с пунктами, точно, что вы хотите, чтобы произошло в вашем документе и когда, независимо от того, как вы можете это осуществить.

Это сделает ваши цели простыми и лаконичными, поэтому ваш код будет намного короче и понятнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...