javascript - 如何通过 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>
解决方案
删除您的 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);
}
无论如何,显示工具提示似乎有点过头了。您可能想在一张纸上写下要点,确切地说您希望在文档中发生什么以及何时发生,无论您可能以何种方式实现它。
这将使您的目标保持简单明了,因此您的代码将更短更清晰。
推荐阅读
- angular - ionic - RXJS 错误:rxjs_Observable__.Observable.combineLatest 不是函数
- r - 要替换的项目数不是R中替换长度错误的倍数
- javascript - 在 ReactJS 中覆盖父组件方法
- java - How to get the body of an Email in Text or string format not in HTML
- java - BouncyCastle 验证 secp256k1 公钥生成
- angular - Custom parent container for Angular material overlay container?
- azure - Reading Azure container instance secret volumes from asp.netcore 2.2 web app
- javascript - Instagram API 未定义图像 URL (Node.Js)
- python-3.x - Sqlite3 操作错误:靠近“REFERENCES”语法错误
- laravel - 提交用户创建表单时出现 500 服务器错误