How to Access the Contents of an Svg File in an <Img> Element

Do I use img, object, or embed for SVG files?

I can recommend the SVG Primer (published by the W3C), which covers this topic: http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML

If you use <object> then you get raster fallback for free*:

<object data="your.svg" type="image/svg+xml">
<img src="yourfallback.jpg" />
</object>

*) Well, not quite for free, because some browsers download both resources, see Larry's suggestion below for how to get around that.

2014 update:

  • If you want a non-interactive svg, use <img> with script fallbacks
    to png version (for older IE and android < 3). One clean and simple
    way to do that:

    <img src="your.svg" onerror="this.src='your.png'">.

    This will behave much like a GIF image, and if your browser supports declarative animations (SMIL) then those will play.

  • If you want an interactive svg, use either <iframe> or <object>.

  • If you need to provide older browsers the ability to use an svg plugin, then use <embed>.

  • For svg in css background-image and similar properties, modernizr is one choice for switching to fallback images, another is depending on multiple backgrounds to do it automatically:

    div {
    background-image: url(fallback.png);
    background-image: url(your.svg), none;
    }

    Note: the multiple backgrounds strategy doesn't work on Android 2.3 because it supports multiple backgrounds but not svg.

An additional good read is this blogpost on svg fallbacks.

Load an SVG image where the elements become part of the DOM

As @diopside and @RobertLongson mention in the comments, the question was asked a different way here: Do I use <img>, <object>, or <embed> for SVG files?

The solution was to use <object> and embed the SVG in that. Now I can interact with it yet the browser doesn't need to reload the image each time the page loads.

I want to get file content by img element isn't async, (src is svg)

Given your project it seems like it would make a lot more sense to do it the other way around:

  • Fetch the resource
  • Read it as text
  • Load the fetched resource in the images (as a blob: URL)

This way, when you start dragging your elements around you already have their markup version:

const images = document.querySelectorAll("img[data-src]");
images.forEach( async (img) => {
// we store the actual src in a data- attribute
// we will only fetch it from here
const resp = await fetch(img.getAttribute("data-src"));
const as_blob = resp.ok && await resp.blob();
// read as text to get the markup
const markup = await as_blob.text();
// create a blob: URL so we can display the image
const url = URL.createObjectURL(as_blob);
img.src = url;
// once the image is loaded we can revoke the blob: URL
// this will allow the Blob to be Garbage Collected
img.addEventListener("load", (evt) => URL.revokeObjectURL(url), {
once: true
});
img.addEventListener("dragstart", (evt) =>
evt.dataTransfer.setData("text/plain", markup)
);
});

const div = document.getElementById("div");
div.addEventListener("dragover", (evt) => evt.preventDefault() );

div.ondrop = (evt) => {
const data = evt.dataTransfer.getData('text/plain');
console.log(data);
};
<img id="img" draggable="true" data-src="https://upload.wikimedia.org/wikipedia/commons/4/4a/Commons-logo.svg" width="50px" height="50px" />

<div id="div" style="background-color: #123; width: 400px; height: 300px;"></div>

How to use link to SVG file inside image element?

Yes, you can use SVG-file inside image tag in SVG! But this tag does not have src attribute. This attribute is from HTML img tag.

Inside image tag you have to use href attribute or also xlink:href attribute (but it is deprecated since SVG 2) for this purpose.

<svg width="50" height="150">       
<image href="https://developer.mozilla.org/static/platforms/mobile.d9737f9e22aa.svg" width="50" height="150"/>
</svg>


Related Topics



Leave a reply



Submit