如何将ResizeObserver应用于SVG元素?

5
我希望能够响应 HTML 文档中 SVG 元素大小的变化。经过一些研究,我发现 ResizeObserver API 可以监听给定的 HTML 或 SVG 元素的大小变化(stackoverflowMDN)。不幸的是,我无法使其在 SVG 元素上起作用。

我的示例包含一个 DIV 元素、一个 SVG 元素和一个 ResizeObserver。

const svg = document.querySelector('#svg')
const svgInfo = document.querySelector('#svg-info')
const div = document.querySelector('#div')
const divInfo = document.querySelector('#div-info')

const svgObserver = new ResizeObserver(() => {
  svgInfo.textContent = svg.clientWidth
})
svgObserver.observe(svg)
const divObserver = new ResizeObserver(() => {
  divInfo.textContent = div.clientWidth
})
divObserver.observe(div)
<svg id="svg" style="background-color: red; width: 100%; height: 50px"></svg>
<div id="svg-info">initial</div>
<div id="div" style="background-color: blue; width: 100%; height: 50px"></div>
<div id="div-info">initial</div>

我希望当调整元素大小时,例如调整窗口大小时,两个ResizeObservers都会触发,这将由两个信息标签的变化可见。 然而,在我的情况下(Mozilla Firefox 84.0),只有DIV元素的信息标签发生了变化。

作为一种解决方法,我可以考虑用DIV包装我的SVG作为代理。尽管如此,我仍然想知道为什么ResizeObserver和SVG的组合不起作用。


4
根据规范,据我所知SVG目前无法被观察到,但是有意愿让它们能够被观察。这是由于技术原因,因为它们使用边界框而不是内容框。因此ResizeObserver无法观察到变化并触发事件。这是他们正在解决的当前限制。我不知道是否有任何可用的解决方法。 - r3wt
截至目前,仅Chromium浏览器似乎会在内容框改变时推送ResizeObserver更新。其他引擎还没有这么做,更糟糕的是,如果你依赖它们的ResizeObserverEntry参数,“更新”将会给你contentRect的边界框值——令人困惑! 我建议暂时采用Krischna的解决方案,依赖一个包含元素... - tdhsmith
1个回答

1

您需要将SVG包装在DIV元素中,并观察包装的DIV元素,如下所示:

const svg = document.querySelector('#svg')
const svgInfo = document.querySelector('#svg-info')
const div = document.querySelector('#div')
const divInfo = document.querySelector('#div-info')

const svgObserver = new ResizeObserver(() => {
  svgInfo.textContent = svg.clientWidth
})
svgObserver.observe(svg)
const divObserver = new ResizeObserver(() => {
  divInfo.textContent = div.clientWidth
})
divObserver.observe(div)
<div id="svg" style="background-color: red; width: 100%; height: 50px">
    <svg style="width: 100%; height: 100%"></svg>
</div>
<div id="svg-info">initial</div>
<div id="div" style="background-color: blue; width: 100%; height: 50px"></div>
<div id="div-info">initial</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接