我正在添加一个带有<br>html标签的工具提示.它在chrome中运行良好但在firefox上运行不正常.
我的代码:
var dot = svg.append("g")
.attr("class", "dots")
.selectAll(".dot")
.data(interpolateData(1))
.enter().append("circle")
.attr("class", "dot")
// Add a title.
dot.append("title")
.each(function() {
var d = d3.select(this);
d3.select(this).select("title")
.html(function(d,i) { return d.name + ": " + Math.round(Number(d.avg)) + " avg each month <br>" + d.name + ": Build of " + Math.round(Number(d.Checkin)) + " hrs each month";});
Run Code Online (Sandbox Code Playgroud)
工具提示应该以2行显示.它在chrome中工作正常但在firefox中没有.
SVG <title>元素在浏览器之间处理不一致,因为它具有类似的功能,但与HTML title属性相比具有不同的规则.浏览器似乎有选择地选择它们适用于SVG的HTML规则以及如何应用.
该SVG <title>元素的规格说明:
标题主要用于辅助功能.
浏览器可以将标题显示为工具提示.
但是,必须显示独立SVG文档中的顶级标题(通常在标题栏中,与HTML <title>元素相同).
标题可能包含来自其他名称空间的内容,具有适当的XML名称空间属性,但没有迹象表明在创建工具提示时应如何呈现这些内容.
任何不在另一个名称空间中的内容都应该受到一般SVG空格处理规则的约束,这些规则要求忽略换行符.
在HTML title属性规格表明:
标题代表关于该元素的其他"咨询信息".
浏览器必须向用户提供标题信息,最好是以与设备无关的方式(尽管大多数只在悬停时显示).
显示工具提示时,必须遵守属性中的换行符.
不允许其他标记(因为它是属性,而不是HTML代码).
但...
浏览器制造商重复使用代码显示HTML工具提示以显示SVG工具提示,因此事情变得令人困惑.
跟随这个小提琴(记住这适用于HTML文档中的内联SVG):http://fiddle.jshell.net/5npxba9L/6/
SVG中的硬换行和额外空格<title>:
被保存在铬36,歌剧24和Firefox 31(即,HTML属性规则被应用)
在IE 11中被忽略(即,应用了SVG空白规则)
<br/>SVG中的标记元素<title>:
从Firefox 31中的工具提示中删除
在Chrome 36,Opera 24和IE 11中显示为换行符
当使用XML名称空间前缀时,在所有浏览器中都被完全忽略(这在XHTML文档中可能有所不同)
SVG中的其他标记元素<title>,例如SVG <tspan>元素:
从Firefox 31和IE 11中的工具提示中删除
在Chrome和Opera中显示为纯文本(即打印出的尖括号)
在HTML标题属性中保留硬换行符和额外的空格,并且在所有测试的浏览器中(正确地)将额外标记呈现为纯文本
因此,完全hacky而不是根据规范获取内联SVG中的多行工具提示的方法是使用两个 <br/>标记(未命名空间或默认命名空间中的更改)和<title>元素中的硬换行符:
<svg>
<circle cx="250" r="50">
<title><span xmlns="http://www.w3.org/1999/xhtml">Title with <br/>
a line break</span></title>
</circle>
</svg>
Run Code Online (Sandbox Code Playgroud)
适用于当前版本的Chrome,Opera,Firefox和IE(尚未在Safari或移动设备上测试),尽管基于webkit的浏览器将创建一个额外的空白行.
但是请注意:selection.html()在大多数浏览器中,您将无法使用d3 方法创建上述标记,因为该函数依赖于HTMLElement.innerHTMLDOM属性,而该属性未在SVG元素上定义.您需要分别创建文本节点和<br>元素.最简单的方法是使用虚拟HTML元素作为父元素,使用innerHTML属性创建混合内容,然后将其附加到title元素:
dot.enter().append("circle")
.attr("class", "dot")
.attr("r", "50")
.attr("cx", function(d,i){return i*100 + 50;})
.append("title")
.append(function(d, i){
//when the parameter to `append()` is a function
//it will be run for each element in the active selection
//(in this case, the title elements)
//and must return the actual element node to append.
var span = document.createElement("span");
span.innerHTML = "This is element <br/>\n #" + i;
//the \n will be converted in Javascript to a line break
return span;
});
Run Code Online (Sandbox Code Playgroud)
http://fiddle.jshell.net/cLLsgdmk/
这一切都是好奇心.如果您需要更可靠的解决方案,请按照Lars的回答获取如何创建<foreignObject>工具提示的链接,或者查看此Codepen演示,了解有关如何使用Javascript覆盖绝对位于<div>SVG顶部的信息.