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>