1

I have an external SVG file which contains the following SVG definition:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>

The SVG has multiple paths, so for me to be able to change colours of individual paths I need to be able to load the SVG file contents into a Javascript variable like this:

var svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';

Then I can use conditional statements to alter the colours e.g.

switch(centerId) {
    case 1:
        svgSource = svgSource.replace("#ffbf00", "#005D00");
        break;
    case 2:
        svgSource = svgSource.replace("#ffbf00", "#A20000");
        break;
    case 3:
        svgSource = svgSource.replace("#ffbf00", "#ffbf00");
        break;
}

I could define and use the inline SVG code hard coded into the Javascript as shown, but for maintenance and continuity it would be much better to use existing, centralised, external SVG files.

How can I load the contents of the SVG file into a javascript variable/object?

  • Sure you can. You have the string. You just have to split the data into properties and assign. It won't be easy tho. – Jarne Jun 08 '22 at 13:11
  • I'm not sure how that helps me load an external svg file contants into a javascript variable? – arresteddevelopment Jun 08 '22 at 13:15
  • You can make an AJAX request for the SVG URL, then you will get the SVG code in text form ... And then you can insert that into your document directly. (If you embed the SVG via `img`, then you won't have JS access to its "entrails.") – CBroe Jun 08 '22 at 13:46
  • Add your own JS to the (standard JavaScript) ```` Web Component: https://dev.to/dannyengelman/load-file-web-component-add-external-content-to-the-dom-1nd – Danny '365CSI' Engelman Jun 08 '22 at 15:59

2 Answers2

0

One solution is to load the svg image by setting the innerHTML property of an arbitrary container to your svg string.

This then gives you two options: firstly, for heavy changes, you have access to each path as part of the DOM and can maniulate them using javascript. This simply requires making a reference to container.children[0]; Alternatively, for simple changes such as colour changes, it makes each element directly targetable by style rules where you can specify colours in the usual way.

The snippet illustrates adding the svg to the dom using your string, and resets some colours with simple style rules. Making a reference for changes using javascript is shown commented at the foot of the code.

let svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';

const container = document.getElementsByTagName('div')[0];
container.innerHTML = svgSource;

// for js manipulation:
// svgObject = container.children[0];
div {
width: 50%;
}

.st0 {
 fill: red;
}

.st1 {
 fill: yellow;
}

circle {
  fill: green;
}
<div>
</div>
Dave Pritlove
  • 2,601
  • 3
  • 15
  • 14
  • Hi, Thanks for the tips, but this tackles 'hot to change styles in an SVG' and has nothing to do with accessing a file and loading it into javascript in the first place. I totally understand how to use the style tags to modify colours etc, but not all the SVG files we use have them and I am trying to re-use centralised SVG files. – arresteddevelopment Jun 09 '22 at 16:15
  • on reflection I think I misunderstood your question. It should be possible to read a file to a variable using `fetch`. – Dave Pritlove Jun 09 '22 at 16:35
0

CSS Styling

Try using CSS to style the paths instead of replacing parts of source code.

Concept code example, using the style attribute of svg elements to apply some CSS:

"use strict";
const svg = document.querySelector("svg");
const paths = svg.querySelectorAll("path");
paths[0].style = "fill: #FF0000;"
svg.querySelector("circle").style = "fill: rebeccapurple";
svg {
   height: 150px;
   width: 100px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>

Potentially you could improve on this by writing svg source that expects to be styled by CSS instead of being over-ridden by style attribute values.


See also: How to use external SVG in HTML?


Getting the source of an external SVG file

An external svg file can be included in HTML using a pair of <object> tags. For example if "svg-file.svg" is in the same directory as the HTML file:

<object type="image/svg+xml" id="mySVG"
  data="svg-file.svg"
  width="100"
  height="150"
></object>

Subject to security policies: the svg file must be from the same domain and served from a network or localhost server - due to blanket security restriction placed on local files, the source of svg files loaded using the file:// protocol. can't be accessed.

Picking up the svg source is a bit obscure. This worked for me after page load, using the above HTML:

window.onload = ()=> {
   console.log("loaded");
   const svgObject = document.querySelector("#mySVG");
   const svg = svgObject.getSVGDocument().documentElement;
   const svgSource = svg.outerHTML;
   console.log("svgElement, tag name '%s' ", svg.tagName, svg);
   console.log("svgSource: ", svgSource);
   console.log("path.st0: ", svg.querySelector('.st0'));
};
traktor
  • 17,588
  • 4
  • 32
  • 53
  • Thanks, really useful tip and I will make use of it, but my question is how to get the SVG loaded into Javascript from an outside source in a way that allows me to implement solutions such as yours. – arresteddevelopment Jun 09 '22 at 16:19