<svg>
<text id="test" x="0" y="15"></text>
</svg>
,
d3.select("#test").text("aaa");
或
document.getElementById("test").textContent("aaa");
工作正常。但我需要在文本中添加样式。现在:
d3.select("#test").text('aaa <tspan style="font-weight:bold">bbb</tspan> ccc');
遗憾的是,不起作用,因为该参数被视为纯字符串。针对此问题的最佳跨浏览器解决方案是什么?
答案 0 :(得分:5)
主要问题是SVG元素没有innerHTML
属性,您需要自己创建所有子节点。但是,您可以通过仅使用此字符串创建临时DOM对象,将HTML字符串转换为样式tspan
s(无)字符串解析魔法。之后,您可以使用d3创建正确的tspans元素。
var text = d3.select("#test"), tmp = document.createElement("text"); //create tmp
tmp.innerHTML = 'aaa <tspan style="font-weight:bold">bbb</tspan> ccc' //create HTML children (not yet an SVG!)
var nodes = Array.prototype.slice.call(tmp.childNodes) //create a real array from the childNodes variable
nodes.forEach( function(node) {
text.append("tspan")
.attr("style", node.getAttribute && node.getAttribute("style"))
.text(node.textContent)
})
剩余问题:此解决方案不支持tspans中需要遍历源元素childNodes
的子节点,复制style
(可能还有其他属性)从子节点和append
新的子tspan
元素(和其他可能的标签)到相应的父tspans(或其他标签)。这最终将导致一个sub tspan兼容的解析器来完全解决这个问题。
编辑:还有一个更通用的innerSVG shim,它也可以处理子节点。
还有一些其他解决方案应该可行,但目前已被打破。正如其他人已经指出的那样,直接在jQuery或d3中使用.html()
不起作用,因为它们依赖于innerHTML
。
//not working
$("#test").html(...); d3.select("#test").html(...)
通过jQuery复制和追加(类似于我的工作解决方案)也被打破了。它创建了正确的DOM,但未显示tspan(在Firefox和Chrome中尝试过):
//creates correct DOM, but disables/hides the created tspan
var tmp = $("<text>")
tmp.html('aaa <tspan style="font-weight:bold">bbb</tspan> ccc')
$("#test").append( Array.prototype.slice.call(tmp[0].childNodes) )
根据W3C规范,应该可以mix tspan和TextNodes。
答案 1 :(得分:0)
var t = d3.select("#test")
t.append("tspan").text("aaa ");
t.append("tspan").text("bbb").style("font-weight","bold");
t.append("tspan").text(" ccc");
答案 2 :(得分:-1)
document.getElementById("test").style.fontWeight="bold"
上述内容会改变一切。
但你可以试试innerHTML方法:
document.getElementById("test").innerHTML('aaa <tspan style=\"font-weight:bold\">bbb</tspan> ccc');
答案 3 :(得分:-3)
试试这个
d3.select("#test").html('aaa <tspan style="font-weight:bold">bbb</tspan> ccc');