javascript 未显示 SVG 内的 HTML 元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15148481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML element inside SVG not displayed
提问by swenedo
I am struggeling with the foreignObject
in SVG. I want to add text inside a rect
, and to get auto text wrap I have chosen to use HTML. The description of foreignObject
can be found here.
我foreignObject
在 SVG 中挣扎。我想在 a 中添加文本rect
,为了获得自动换行,我选择了使用 HTML。的描述foreignObject
可以在这里找到。
I am working with D3, and this is my data:
我正在使用 D3,这是我的数据:
var cds = [
{"uid":"U12","sid":"16","statement":"Movies","x":10,"y":10},
{"uid":"U20","sid":"17","statement":"Food","x":10,"y":170},
{"uid":"U22","sid":"15","statement":"Sport","x":10,"y":330}
];
I add a card for each datum and want to display the "statement" from the data.
我为每个数据添加了一张卡片,并希望显示数据中的“声明”。
var cardsize = { width : 150, height : 150 };
var svg = d3.select("body").append("svg:svg")
.attr("width", 170)
.attr("height", 490);
var card = svg.selectAll("rect")
.data(cds)
.enter().append("svg:g")
.attr("class", "card")
.attr("transform", function(d,i) {
d.x = 10;
d.y = 10+i*(10+cardsize.height);
return "translate(" + d.x + "," + d.y + ")";
});
card.append("svg:rect")
.attr('width', cardsize.width)
.attr('height', cardsize.height)
card.append("svg:foreignObject")
.attr('width', cardsize.width)
.attr('height', cardsize.height)
.append('p')
.attr("class","statement")
.text(function(d) { return d.statement; });
The output of a card is this:
卡的输出是这样的:
<g class="card" transform="translate(10,330)">
<rect width="150" height="150"></rect>
<foreignObject width="150" height="150"><
p class="statement">Sport</p>
</foreignObject>
</g>
I can't see the text in the (mac) browsers I have tested (Safari 6.0.2, Chrome 25.0.1364.99, Firefox 18.0.2). W3's validatordoesn't like the output, and give me this error for each card:
我在测试过的 (mac) 浏览器(Safari 6.0.2、Chrome 25.0.1364.99、Firefox 18.0.2)中看不到文本。W3 的验证器不喜欢输出,并为每张卡给我这个错误:
Element foreignObject not allowed as child of element g in this context.
在此上下文中,不允许元素 foreignObject 作为元素 g 的子元素。
So my question is, where is the problem, and why is foreignObject not allowed as a child of a g
element?
所以我的问题是,问题出在哪里,为什么不允许foreignObject 作为g
元素的子元素?
I am also wondering why .html(function(d) { return d.statement; });
doesn't work (no output). But .text(function(d) { return d.statement; });
works fine?
我也想知道为什么.html(function(d) { return d.statement; });
不起作用(没有输出)。但.text(function(d) { return d.statement; });
工作正常吗?
Here is a fiddle.
这是一个小提琴。
回答by Christopher Chiche
Short answer
简答
Specify the namespace in all tags in a foreignObject: replace .append("p")
by .append("xhtml:p")
and it will work: http://jsfiddle.net/EHzcR/2/
在foreignObject的所有标签中指定命名空间:replace .append("p")
by .append("xhtml:p")
,它将起作用:http: //jsfiddle.net/EHzcR/2/
Long answer
长答案
In the context of foreign objects, <p></p>
is not recognized as a xhtml
paragraph. Why? Simply because the namespace xhtml
is not included in the foreignObject
context (a foreignObject
might contain anything (xml
formated data for example) so it doesn't consider the input as html if you don't explicitly say it.).
在异物的上下文中,<p></p>
不被识别为xhtml
段落。为什么?仅仅因为命名空间xhtml
不包含在foreignObject
上下文中(aforeignObject
可能包含任何内容(xml
例如格式化数据),因此如果您没有明确说明,它不会将输入视为 html。)。
So the p
tag is considered as a custom tag, not as a xhtml
tag. Thus, as the web browser doesn't recognize the tag p
in the tags it knows, so it just doesn't interpret it and its content, even if it exists, it won't throw an error as well because this content might be totally valid, just not for its direct use.
所以p
标签被视为自定义标签,而不是xhtml
标签。因此,由于 Web 浏览器无法识别p
它所知道的标签中的标签,因此它只是不解释它及其内容,即使它存在,它也不会抛出错误,因为该内容可能完全是有效,只是不能直接使用。
It is fun to see that you always specify the namespace svg
even if it is not necessary and how we all forget that the p
, div
... also have a very popular namespace.
很高兴看到您总是指定命名空间,svg
即使它不是必需的,而且我们都忘记了p
, div
... 也有一个非常流行的命名空间。
The selection.html()
function doesn't work because in its implementationit uses the .innerHTML()
function of the element, but here, the foreignObject, not being an html element, doesn't have such a function.
该selection.html()
函数不起作用,因为在它的实现中它使用了.innerHTML()
元素的函数,但在这里,不是 html 元素的 foreignObject 没有这样的函数。
回答by mg1075
I can't tell from your question whether or not you can actually view the text in the foreignObjects? (And if your answer is "yes", then what browser are you using?).
我无法从您的问题中判断您是否可以实际查看 foreignObjects 中的文本?(如果您的回答是“是”,那么您使用的是什么浏览器?)。
I'm looking forward to other answers here, because the method below does not seem optimal to me, but it does get most of the way there.
我期待着这里的其他答案,因为下面的方法对我来说似乎不是最佳的,但它确实可以做到大部分。
Using Chrome, and attempting to generate the <body xmlns="http://www.w3.org/1999/xhtml">
tag inside the foreignObject as per the W3C example, and then the <p>
inside the <body>
, left the text unable to be seen for me. But then just leaving the inner <body>
out, and adding a class to style the foreignObject, produced the desired result.
使用 Chrome,并尝试<body xmlns="http://www.w3.org/1999/xhtml">
按照W3C 示例在 foreignObject 内部生成标签,然后在<p>
内部<body>
,让我无法看到文本。但是然后只留下内部<body>
,并添加一个类来设置foreignObject的样式,就产生了预期的结果。
Updated portions of code added below:
更新了下面添加的代码部分:
D3 section for adding foreignObject text
用于添加foreignObject 文本的D3 部分
svg.selectAll("foreignObject")
.data(cds)
.enter()
.append("foreignObject")
.attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility")
.attr('width', cardsize.width)
.attr('height', cardsize.height)
.attr("x", 10)
.attr("y", function (d, i) { return 10 + i * (10 + cardsize.height) })
.attr("class", "fo-text")
.text(function (d) { return d.statement; });
CSS
CSS
.fo-text {
padding: 5px 10px;
font: 300 14px "Helvetica Neue", sans-serif;
color: #000;
}