在 SVG 中进行 Ajax 更新会破坏 getBBox,有解决方法吗?

发布于 2024-11-16 03:14:30 字数 694 浏览 4 评论 0原文

我有一个 SVG 页面,其中包含一些复杂的图表;我正在尝试添加通过按需 Ajax 调用插入更多复杂性的代码。这大部分工作正常,但插入的节点行为不正常。特别是 getBBox() 在某些元素上失败,在 Firefox 中,错误是这样的:

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]

问题似乎与此有关: https://bugzilla.mozilla.org/show_bug.cgi?format=multiple& ;id=612118 但就我而言,对象肯定已渲染,我可以看到它们。

任何见解或解决方法表示赞赏。不幸的是,我无法轻松地指出一个示例,因为这依赖于服务器交互。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

末蓝 2024-11-23 03:14:30

请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=612118 (SVGLocatable.getBBox() 会失败,除非附加并呈现它所应用的 SVG 元素)。

您必须将元素放入 SVG,并且 style.display 必须为非“none”

另请参阅 SVG 'getBBox' 在 jQueryUI 选项卡中失败

我的解决方法问题通过将文本放置在不可见区域([-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!");

获取宽度/高度:

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

并在计算宽度/高度后将文本放置到必要的位置(其中需要宽度/高度以确定文本的位置):

text.moveTo(off, off + textH);

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);
凡间太子 2024-11-23 03:14:30

,也会出现 NS_ERROR_FAILURE 错误消息

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

如果您尝试计算直接附加到 HTML DOM 并且没有父级 SVGElement 的边界框 SVGSVGElement。示例(您可以在 Scratchpad 中运行代码,在 Firefox 中运行 Shift+F4):

text 直接附加到 body

这会失败,因为 < ;html> 不允许。

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 附加到 svg

这有效。

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]
*/

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]
*/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文