javascript - 在纯 JavaScript 中捕获 SVG onresize() ?

标签 javascript svg event-handling resize

我正在用纯 JavaScript 编写一个应用程序,并且想要定义一个 draw() 方法,每当调整 SVG 大小时都会调用该方法。不幸的是,简单地分配 svg.onresize = draw 不起作用,等效的 svg.AddEventListener('resize', draw) 也不起作用。

<html><body style="margin:0">

<svg id="svg" width="100%" height="100%"></svg>

<script>

let svg = document.getElementById("svg");

function line(x1, y1, x2, y2)
{
    let e = document.createElementNS(svg.namespaceURI, 'line');
    e.setAttribute('x1', x1);
    e.setAttribute('y1', y1);
    e.setAttribute('x2', x2);
    e.setAttribute('y2', y2);
    e.setAttribute('style', 'stroke:#000');
    svg.appendChild(e);
}

function frame_rect(r)
{
    let e = document.createElementNS(svg.namespaceURI, 'rect');
    e.setAttribute('x', r.x);
    e.setAttribute('y', r.y);
    e.setAttribute('width', r.width);
    e.setAttribute('height', r.height);
    e.setAttribute('style', 'stroke:#000;fill:none');
    svg.appendChild(e);
}

function draw()
{
    svg.innerHTML = ''; // remove all elements from the SVG
    let r = svg.getBoundingClientRect();
    line(r.x,r.y,r.x+r.width,r.y+r.height);
    line(r.x,r.y+r.height,r.x+r.width,r.y);
    frame_rect(r);
}
draw();


// onresize = draw;
// Works if entire page is resized, or developer tools opened.
// But misses other resize causes like splitter dragged, tab expanded, etc.

// svg.onresize = draw;
svg.addEventListener('resize', draw);
// Either of the above *should* work, per:
//
//   https://developer.mozilla.org/en-US/docs/Web/API/SVGElement
//
// But neither does, even if the entire window is resized.

svg.onclick = draw;
// Just to show that draw() can be called in response to an event.

</script></body></html>

正如评论中所解释的,我可以使用 window.onresize,但这是一个 hack,它只会捕获由整个窗口大小调整引起的 SVG 大小调整。好的,如果由于打开开发人员工具而调整 SVG 的大小,它也恰好可以工作,但这可能是因为这也会调整整个窗口的大小。

此外,svg.onclick = draw 会导致 SVG 响应鼠标单击而重新绘制,因此看起来我正在附加 draw() 处理程序到正确的对象。为什么 onclick 在捕获事件的能力方面与 onresize 有所不同?

捕获从任何源传播的 SVG 大小调整(而不仅仅是窗口大小调整)的正确方法是什么?

最佳答案

浏览器似乎不支持 SVGResize 事件。但在窗口调整大小事件处理程序中检查 SVG 大小是否已更改非常简单。

let svg = document.getElementById("svg");
let lastSize = null;

function line(x1, y1, x2, y2)
{
    let e = document.createElementNS(svg.namespaceURI, 'line');
    e.setAttribute('x1', x1);
    e.setAttribute('y1', y1);
    e.setAttribute('x2', x2);
    e.setAttribute('y2', y2);
    e.setAttribute('style', 'stroke:#000');
    svg.appendChild(e);
}

function frame_rect(r)
{
    let e = document.createElementNS(svg.namespaceURI, 'rect');
    e.setAttribute('x', r.x);
    e.setAttribute('y', r.y);
    e.setAttribute('width', r.width);
    e.setAttribute('height', r.height);
    e.setAttribute('style', 'stroke:#000;fill:none');
    svg.appendChild(e);
}

function resize(evt)
{
    let r = svg.getBoundingClientRect();
    if (lastSize && (lastSize.width !== r.width || lastSize.height !== r.height))     {
      draw();
    }
}

function draw()
{
    svg.innerHTML = ''; // remove all elements from the SVG
    let r = svg.getBoundingClientRect();
    line(r.x,r.y,r.x+r.width,r.y+r.height);
    line(r.x,r.y+r.height,r.x+r.width,r.y);
    frame_rect(r);
    lastSize = r;
}
draw();

window.addEventListener('resize', resize);
body {
  margin: 0;
}
<svg id="svg" width="100%" height="100%"></svg>

关于javascript - 在纯 JavaScript 中捕获 SVG onresize() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56620664/

相关文章:

closures - 如何在闭包中保存变量的值

javascript - AngularJS:ng-if 不能与 ng-click 结合使用?

svg - d3.js - 通过 svg 路径绘制 4 个点的椭圆形状

events - Smalltalk 中的事件处理(squeak)

Javascript 自增数组

javascript - 如何将日历开始日期布局从星期日更改为星期一?

css - SVG 中文本的背景色

javascript - 在同一位置放置动态形状

c# - 在 GetIncationList() 之后获取合适的 eventHandler

node.js - 如何避免将事件发射延迟到事件循环的下一个滴答?