Doing Ajax updates in SVG breaks getBBox, is there a workaround?

拜拜、爱过 提交于 2019-12-04 03:46:14
gavenkoa

See https://bugzilla.mozilla.org/show_bug.cgi?id=612118 (SVGLocatable.getBBox() fails unless the SVG element it is applied to is attached and rendered).

You must put your element to SVG and style.display must be non-"none".

See also SVG 'getBBox' fails in a jQueryUI tab

I workaround issue by placing text at invisible area ([-1000; -1000]):

function SVGlibText(x, y, text) {
    this.value = document.createElementNS(SVGlibBase.svgNS, "text");
    this.value.setAttribute("x", x);
    this.value.setAttribute("y", y);
    this.value.textContent = text;
}
SVGlibText.prototype.moveTo = function(x, y) {
    this.value.setAttribute("x", x);
    this.value.setAttribute("y", y);
    return this;
}
SVGlibText.prototype.getW = function() {
    return this.value.getBBox().width;
}
SVGlibText.prototype.getH = function() {
    return this.value.getBBox().height;
}

var text = new SVGlibText(-1000, -1000, "Hello world!");

getting width/height:

var textW = text.getW();
var textH = text.getH();

and placing text to necessary position after calculation with width/height (which require width/height in order to determine position of text):

text.moveTo(off, off + textH);

The NS_ERROR_FAILURE error message, or

Exception { message: "", result: 2147500037, name: "NS_ERROR_FAILURE", ...}`)

also occurs if you try to calculate the bounding box of an SVGElement which is attached directly to the HTML DOM and does not have a parent SVGSVGElement. Examples (you can run the code in Scratchpad, Shift+F4 in Firefox):

text directly attached to body

This fails because <html><body><g></g></body></html> is not allowed.

var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
document.body.appendChild(text)
text.getBBox()
/*
Exception: [Exception... "Failure"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: Scratchpad/2 :: <TOP_LEVEL> :: line 3"  data: no]
*/

text attached to svg

This works.

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
svg.appendChild(text);
document.body.appendChild(svg)
text.getBBox()
/*
[object SVGRect]
*/
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!