2

I've got 3 files: test.html, test.js and test.svg

I'm trying to call the different files into HTML but the file svg don't work

test.html

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Using SVG as an object</title>
    <link href="index.css" rel="stylesheet" />
</head>
<body>
    <h1>Test</h1>
    <script type="text/javascript" src="test.js"></script>


    <object data="test.svg" width="300" height="300"> </object>  <!-- Not working -->


    <input type="button" value="Start Animation" onclick="startAnimation();">
    <input type="button" value="Stop Animation" onclick="stopAnimation();"> 
</body>
</html>

test.js

var timerFunction = null;

    function startAnimation() {
        if(timerFunction == null) {
            timerFunction = setInterval(animate, 20);
        }
    }

    function stopAnimation() {
        if(timerFunction != null){
            clearInterval(timerFunction);
            timerFunction = null;
        }
    }

    function animate() {
        var circle = document.getElementById("circle1");
        var x = circle.getAttribute("cx");
        var newX = 2 + parseInt(x);
        if(newX > 500) {
            newX = 20;
        }
        circle.setAttribute("cx", newX);
    }

test.svg

<svg width="500" height="100">
    <circle id="circle1" cx="20" cy="20" r="10"
            style="stroke: none; fill: #ff0000;"/>
</svg>

I don't understand why I can't insert svg file with object

Thanks for your help

zefzef aa
  • 67
  • 6
  • Why would you need to use an object tag? Just use the svg directly. Originally this was used to run flash or something, it's not really needed nowadays. – cloned May 27 '21 at 09:00
  • Kindly take a look at this post for more insight [Link](https://vecta.io/blog/best-way-to-embed-svg) – Ondiek Elijah May 27 '21 at 09:05
  • So, it's better to use directly inside htm? Bcs imagine if i've got a lot of svg ? – zefzef aa May 27 '21 at 09:05
  • 1
    Please check path to file and what did console say? Try to specify [viewBox](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox) attribute in svg tag – Greg-- May 27 '21 at 09:05
  • Try an image tag. . And check the console for errors. – Trevor Dixon May 27 '21 at 09:11
  • your SVG file has no namespace defined i.e. no xmlns=... attribute. https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course – Robert Longson May 27 '21 at 11:48

3 Answers3

2

See Dev.To Post: <load-file> Web Component


Use a modern, native W3C standard Web Component <load-svg>

  • it reads the SVG as text
  • adds SVG to shadowDOM as DOM element
  • moves the style element from lightDOM to shadowDOM
    So style is only applied to one SVG

<load-svg shadowRoot src="//graphviz.org/Gallery/directed/fsm.svg">
  <style>
    svg { height:150px } text { stroke: green } path { stroke: red ; stroke-width:3 }
  </style>
</load-svg>
<load-svg src="//graphviz.org/Gallery/directed/fsm.svg">
<!-- all HTML here is overwritten -->
</load-svg>

<script>
  customElements.define('load-svg', class extends HTMLElement {
    async connectedCallback() {
      this.style.display = 'none'; // prevent FOUC (provided Custom Element is defined ASAP!)
      let src = this.getAttribute("src");
      let svg = await (await fetch(src)).text();
      if (this.hasAttribute("shadowRoot")) {
        this.attachShadow({mode:"open"}).innerHTML = svg;
        this.shadowRoot.append(this.querySelector("style") || []);
      } else {
        this.innerHTML = svg;
      }
      this.style.display = 'inherit';
    }
  });
</script>

More complex example: How to make an svg interactive to gather comments/annotations on depicted elements

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • I don't understand how come almost 2 years later, this answer doesn't have a trillion upvotes. I actually gave the first. This is brilliant! – Ricardo Feb 15 '23 at 09:13
0

<object> tags can be used on many elements, including SVG files, and therefore not recognized as image elements, So:

  1. It's not available on image search. So you can use an <img> tag as fallback (optional but recommended)
  2. You should specify the type of the object

So you can change it like this:

    <object type="image/svg+xml" data="test.svg" width="300" height="300">
        <img src="test.svg" />
    </object>

And another problem is the SVG file. Based on MDN documents :

The xmlns attribute is only required on the outermost SVG element of SVG documents. It is unnecessary for inner SVG elements or inside HTML documents.

so you need to add xmlns parameters to the SVG tag on SVG file like this :

<svg width="500" height="100" xmlns="http://www.w3.org/2000/svg">
<circle id="circle1" cx="20" cy="20" r="10"
        style="stroke: none; fill: #ff0000;"/>
</svg>

I made a small simple example that works, checkout this sandBox link

marzzy
  • 706
  • 10
  • 21
  • I updated the answer and also add a sandbox link that works, could you plz check it? @zefzefaa – marzzy May 28 '21 at 06:20
0

You can use svgs directly in the HTML. Easiest is to just use the SVG inside the HTML. You can also re-use an svg shape on a page but then the icons have a shadow-dom boundary.

If you use an object or svg tag, it will render just fine but you will lose all information about classes, IDs and so on in the SVG.

Further Information on SVG on css-tricks

More information about how to group and re-use shapes in SVG on css-tricks (and one more, also on css-tricks)

var timerFunction = null;

function startAnimation() {
  if (timerFunction == null) {
    timerFunction = setInterval(animate, 20);
  }
}

function stopAnimation() {
  if (timerFunction != null) {
    clearInterval(timerFunction);
    timerFunction = null;
  }
}

function animate() {
  var circle = document.getElementById("circle1");
  var x = circle.getAttribute("cx");
  var newX = 2 + parseInt(x);
  if (newX > 500) {
    newX = 20;
  }
  circle.setAttribute("cx", newX);
}
<svg width="500" height="100">
    <circle id="circle1" cx="20" cy="20" r="10"
            style="stroke: none; fill: #ff0000;"/>
</svg>

<input type="button" value="Start Animation" onclick="startAnimation();">
<input type="button" value="Stop Animation" onclick="stopAnimation();">
cloned
  • 6,346
  • 4
  • 26
  • 38