Home > other >  render SVG graphics from AJAX call
render SVG graphics from AJAX call

Time:06-16

I am making an AJAX get request which returns an XML object containing a fully-qualified SVG. In the browser's inspector I can see the response header indicates it is 'application/xml', and I can see the response itself: <svg> .... </svg>, correctly structured with namespace headers etc.

I then try to render the object within a and it is rendering [object Object] instead of the content itself. If the AJAX call populated the var 'src', I write:

element = document.getElementById('myDiv');
element.innerHTML = src;

I have looked at various other articles about this, e.g. using DOMParser, but the best I get is that it renders something like [object XMLElement] etc. Very frustating.

Is there a simple way to just have the actual SVG put between the tags so it renders the graphics therein?

CodePudding user response:

All you need is a native JavaScript Web Component <load-file src="">

customElements.define("load-file", class extends HTMLElement {
  // declare default connectedCallback as sync so await can be used
  async connectedCallback(
    // call connectedCallback with parameter to *replace* SVG (of <load-file> persists)
    src = this.getAttribute("src"),
    // attach a shadowRoot if none exists (prevents displaying error when moving Nodes)
    // declare as parameter to save 4 Bytes: 'let '
    shadowRoot = this.shadowRoot || this.attachShadow({mode:"open"})
  ) {
      // load SVG file from src="" async, parse to text, add to shadowRoot.innerHTML
    shadowRoot.innerHTML = await (await fetch(src)).text()

    // append optional <tag [shadowRoot]> Elements from inside <load-svg> after parsed <svg>
    shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))

    // if "replaceWith" attribute 
    // then replace <load-svg> with loaded content <load-svg>
    // childNodes instead of children to include #textNodes also
    this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
  }
})
<load-file src="//load-file.github.io/heart.svg"></load-file>

Full documentation: https://dev.to/dannyengelman/load-file-web-component-add-external-content-to-the-dom-1nd

CodePudding user response:

You should probably get the rootElement.outerHTML of the object, because it is a XML document that is returned.

$.ajax({
  type: "GET",
  url: "data:image/svg xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHZpZXdCb3g9IjAgMCAxMCAxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cmVjdCB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9ImJsdWUiLz4KPC9zdmc Cgo=",
  dataType: "xml",
  success: function(xml) {
    $('#myDiv').html(xml.rootElement.outerHTML);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myDiv" style="width: 200px"></div>

  • Related