Захватить SVG onresize () в простом JavaScript? - PullRequest
0 голосов
/ 16 июня 2019

Я пишу приложение на простом 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, но это хак, который будет перехватывать только SVG-размеры, вызванные изменением размера всего окна. Хорошо, и это также работает, если SVG изменен из-за открытия инструментов разработчика, но это, вероятно, потому что это также изменяет размер всего окна.

Кроме того, svg.onclick = draw заставляет SVG перерисовываться в ответ на щелчок мышью, поэтому мне кажется, что я прикрепляю обработчик draw() к нужному объекту. Почему onclick отличается от onresize с точки зрения способности отлавливать события?

Как правильно отследить размеры SVG, которые были распространены из любого источника, а не только размеры окна?

1 Ответ

1 голос
/ 16 июня 2019

Похоже, что браузеры не поддерживают событие 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...