SVG获取文本元素的宽度

我正在为SVG文件处理一些ECMAScript / JavaScript,并需要获取text元素的widthheight ,以便可以调整围绕它的矩形的大小。 在HTML中,我可以使用元素上的offsetWidthoffsetHeight属性,但看起来这些属性是不可用的。

这是我需要处理的一个片段。 我需要改变矩形的宽度,每当我改变文字,但我不知道如何获得text元素的实际width (以像素为单位)。

 <rect x="100" y="100" width="100" height="100" /> <text>Some Text</text> 

有任何想法吗?

 var bbox = textElement.getBBox(); var width = bbox.width; var height = bbox.height; 

然后相应地设置矩形的属性。

链接:在SVG v1.1标准中的getBBox()

关于文本的长度,该链接似乎指示BBox和getComputedTextLength()可能会返回稍微不同的值,但是这些值彼此相当接近。

http://bl.ocks.org/MSCAU/58bba77cdcae42fc2f44

这样的兼容性如何?

 function svgElemWidth(elem) { var methods = [ // name of function and how to process its result { fn: 'getBBox', w: function(x) { return x.width; }, }, { fn: 'getBoundingClientRect', w: function(x) { return x.width; }, }, { fn: 'getComputedTextLength', w: function(x) { return x; }, }, // text elements only ]; var widths = []; var width, i, method; for (i = 0; i < methods.length; i++) { method = methods[i]; if (typeof elem[method.fn] === 'function') { width = method.w(elem[method.fn]()); if (width !== 0) { widths.push(width); } } } var result; if (widths.length) { result = 0; for (i = 0; i < widths.length; i++) { result += widths[i]; } result /= widths.length; } return result; } 

这将返回三种方法的任何有效结果的平均值。 如果元素是一个文本元素,你可以改进它来抛出exception值,或者支持getComputedTextLength

警告:正如评论所说, getBoundingClientRect是棘手的。 将其从方法中移除,或仅在getBoundingClientRect将返回良好结果的元素上使用此元素,所以不需要旋转并且可能不会缩放(?)

 document.getElementById('yourTextId').getComputedTextLength(); 

为我工作

不知道为什么,但没有上述方法为我工作。 我用canvas方法取得了一些成功,但我必须应用各种比例因子。 即使使用比例因子,Safari,Chrome和Firefox之间的结果仍然不一致。

所以,我尝试了以下几点:

  var div = document.createElement('div'); div.style.position = 'absolute'; div.style.visibility = 'hidden'; div.style.height = 'auto'; div.style.width = 'auto'; div.style.whiteSpace = 'nowrap'; div.style.fontFamily = 'YOUR_FONT_GOES_HERE'; div.style.fontSize = '100'; div.style.border = "1px solid blue"; // for convenience when visible div.innerHTML = "YOUR STRING"; document.body.appendChild(div); var offsetWidth = div.offsetWidth; var clientWidth = div.clientWidth; document.body.removeChild(div); return clientWidth;