1

In the DOM, one can traverse down into an embedded SVG element using getSVGDocument(). For instance, with an HTML document like this:

<div id="container">
    <embed id="svg-wrap" src="pic.svg"></embed>
</div>

I can access the structure of the SVG itself by doing this:

var svg_wrap = document.getElementById("svg-wrap");
var svg = svg_wrap.getSVGDocument();

How do I reverse this and go from the SVG element up to the enclosing embed and div elements? At least in Chrome 43.0.2357.81, normal DOM traversal methods don't work at the SVG/HTML boundary. For context, I want this so that I can calculate an SVG element's location on the page.

yamad
  • 298
  • 3
  • 9

2 Answers2

2

Using something like a document.getElementById() from inside the SVG itself won't work in accessing nodes in the "main" document structure (the HTML where the "svg-wrap" embed element is put) 'cause the embedded SVG document contents are like "fenced apart" and so you can only directly access node elements that are in the SVG structure itself. This is always true both if the SVG has same or different origin (e.g. different domain) compared to the "main" HTML document.

That said, luckily there is a way you can achieve what you need in case the HTML document and the embedded SVG share the same origin and it is using window.frameElement, for example, like this:

var svg_wrap = window.frameElement;
var svg = svg_wrap.contentDocument;

Note that

Despite the name, frameElement also works for documents embedded using <object> or <embed>

Cit., see: https://developer.mozilla.org/en-US/docs/Web/API/Window/frameElement

and it is well supported in modern browsers.

danicotra
  • 1,333
  • 2
  • 15
  • 34
1

How about the following? Pass it an SVGDocument, and it will return the embed on the page that contains it.

From there you can get the DIV with embedElem.parentNode.

function getEmbedFromSVG(svg)
{
  var allEmbeds = document.getElementsByTagName("embed");
  for (var i=0; i < allEmbeds.length; i++) {
    if (svg === allEmbeds[i].getSVGDocument())
      return allEmbeds[i];
  }
  return null;
}
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181