Doing Ajax updates in SVG breaks getBBox, is there a workaround?
I have an SVG page with some complex diagrams; I'm trying to add code that inserts even more complexity via an Ajax call on demand. This is mostly working, but the inserted nodes don't behave properly. In particular getBBox() fails on some elements, in Firefox the error is something like this:
uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMSVGLocatable.getBBox]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://localhost:1555/svg-scripts.js开发者_开发知识库 :: addBackground :: line 91" data: no]
The problem seems to be related to this one: https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=612118 but in my case the objects are definitely rendered, I can see them.
Any insight or workarounds appreciated. Unfortunately I can't easily point to an example since this relies on a server interaction.
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]
*/
精彩评论