Vous pouvez inclure des fichiers SVG dans votre fichier HTML via les balises embed
object
et svg
.
embed
ou object
nécessite de lier l'image à une URL. (C'est ce que je préfère, parce que je n'aime pas tout ce code SVG dans mon code HTML, donc je voudrais le garder comme ça.)svg
(AFAIK) nécessite d'avoir le code SVG en ligne dans votre code HTML.Comment puis-je inclure des icônes SVG, des images et d'autres fichiers dans mon fichier HTML, sans avoir à mettre tout le code SVG dedans, tout en étant en mesure de leur appliquer des styles? Les appliquer via JS est également très bien.
Lorsque je les inclue via object
ou embed
, je n'arrive pas à y accéder via jQuery, même avec $("#my-svg-div").find("svg")
(qui, soit dit en passant, presque toutes les réponses sur SO dit que je devrais). Je reçois juste undefined
.
Je vous remercie!
Vous pouvez programmer une image SVG en ligne. Une telle image peut être traitée essentiellement de manière identique à un élément <svg>
En ligne réel, y compris la possibilité de lui appliquer des styles.
Si votre image SVG est référencée dans un élément <object>
Ou <iframe>
(e
), vous pouvez l'intégrer comme suit:
e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true), e);
Si votre image SVG est référencée dans un élément <embed>
, Remplacez .contentDocument
Dans le code ci-dessus par .getSVGDocument()
.
Si votre image SVG est référencée dans un élément <img>
, Une stratégie complètement différente, impliquant AJAX et décrite ci-dessous, peut être utilisée pour aligner l'image.
Si vos fichiers d'image SVG externes sont de même origine (par exemple, les images sont chargées au même endroit que le code HTML), alors une approche qui permet de styliser ces images est de les aligner par programme comme suit:
Cette stratégie intégrée vous offre le meilleur des deux mondes:
Vous bénéficiez des avantages de fichiers image séparés, notamment:
Pourtant, vous pouvez toujours faire quoi que ce soit aux images SVG éventuellement intégrées que vous pourriez faire aux éléments <svg>
Qui étaient vraiment à l'origine en ligne, y compris:
<object>
Ou <iframe>
:Vous pouvez incorporer du code SVG référencé en externe comme suit:
// using Vanilla JavaScript (as shown above):
e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true), e);
// using jQuery:
$e.replaceWith($($e[0].contentDocument.documentElement).clone());
... où e
ou $e
sont les variables Vanilla ou jQuery (respectivement) dans lesquelles vous avez sélectionné un référencement SVG externe <object>
ou <iframe>
élément.
<embed>
:Si, à la place, vous utilisez un élément de référence externe-SVG <embed>
, Vous pouvez incorporer le contenu SVG en remplaçant .contentDocument
Dans le code ci-dessus par .getSVGDocument()
(note les parenthèses supplémentaires). Notez que .contentDocument
Ne fonctionne pas avec les éléments <embed>
Tandis que .getSVGDocument()
fonctionne réellement avec les trois types d'élément. Cependant .getSVGDocument()
est déconseillé et ne doit donc être utilisé que si vous avez vraiment besoin d'éléments <embed>
.
<img>
:Aucune des stratégies ci-dessus ne fonctionne pour les éléments <img>
. Pour les intégrer, vous pouvez récupérer l'attribut src
de l'élément <img>
, Faire une demande AJAX pour ce fichier, créer un nouvel élément <svg>
En utilisant le code SVG récupéré et remplacez l'élément <img>
d'origine par le nouvel élément <svg>
. Si vous souhaitez que cette stratégie fonctionne pour les quatre types d'éléments, sachez simplement que l'URL de l'image SVG référencée est conservée dans l'attribut src
de <iframe>
, <embed>
et les éléments <img>
mais dans l'attribut data
d'un élément <object>
. Cette stratégie peut être mise en œuvre comme suit:
// using Vanilla JavaScript:
var xhr = new XMLHttpRequest();
xhr.open("GET", e.getAttribute(e.nodeName === "OBJECT" ? "data" : "src");
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
e.outerHTML = xhr.responseText;
}
};
// using jQuery:
$.get($e.attr($e.prop("nodeName") === "OBJECT" ? "data" : "src"), function(data) {
$e.replaceWith(data.documentElement);
});
L'exemple suivant montre où la stratégie ci-dessus permet et ne permet pas d'appliquer des styles CSS externes aux images SVG à l'origine externes. (Je n'ai pas créé d'extrait de code ou de jsfiddle en raison de la nécessité de référencer des fichiers externes locaux.)
Les deux captures d'écran suivantes montrent le style CSS (triangles rouges) ou son absence (triangles noirs) avant et après l'inlining. Il affiche les résultats des images SVG initialement intégrées dans le code HTML (<svg>
) Ou référencées dans les éléments indiqués (<object>
, <iframe>
, <embed>
Et <img>
). Les trois lignes montrent les résultats de l'incrustation en utilisant les trois stratégies indiquées.
Avant de cliquer sur le bouton, aucune inlining n'a encore été tentée et l'écran ressemble à ceci. Seuls les éléments SVG intégrés (la 1ère colonne) sont stylisés:
Après avoir cliqué sur le bouton, l'inline est tenté et l'écran ressemble maintenant à ceci. Le style CSS a été appliqué avec succès à certains des éléments:
Le code requis pour cet exemple est le suivant:
image.svg
(fichier référencé en externe, c'est-à-dire non incorporé dans le HTML):
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px">
<polygon points="25,5 45,45 5,45 25,5"/>
</svg>
index.html
(évidemment, supprimez la ligne de script jQuery si vous n'utilisez pas jQuery):
<!DOCTYPE html>
<head>
<link href="styles.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="main.js"></script>
</head>
<body>
<button>Click to attempt to inline svg images.</button>
<table>
<tr>
<th></th>
<th>svg </th>
<th>object</th>
<th>iframe</th>
<th>embed </th>
<th>img </th>
</tr>
<tr>
<td>contentDocument</td>
<td><svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"><polygon points="25,5 45,45 5,45 25,5"/></svg></td>
<td><object data="image.svg" type="image/svg+xml"></object></td>
<td><iframe src="image.svg" width="50" height="50" style="border: none;"></iframe></td>
<td><embed src="image.svg" type="image/svg+xml" /></td>
<td><img src="image.svg" /></td>
</tr>
<tr>
<td>getSVGDocument()<br />(deprecated)</td>
<td><svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"><polygon points="25,5 45,45 5,45 25,5"/></svg></td>
<td><object data="image.svg" type="image/svg+xml"></object></td>
<td><iframe src="image.svg" width="50" height="50" style="border: none;"></iframe></td>
<td><embed src="image.svg" type="image/svg+xml" /></td>
<td><img src="image.svg" /></td>
</tr>
<tr>
<td>XMLHttpRequest</td>
<td><svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"><polygon points="25,5 45,45 5,45 25,5"/></svg></td>
<td><object data="image.svg" type="image/svg+xml"></object></td>
<td><iframe src="image.svg" width="50" height="50" style="border: none;"></iframe></td>
<td><embed src="image.svg" type="image/svg+xml" /></td>
<td><img src="image.svg" /></td>
</tr>
</table>
</body>
</html>
styles.css
(seule la ligne polygon
est importante pour démontrer l'inline):
polygon {fill: red;}
table {border-collapse: collapse;}
td, th {border: solid black 1px; padding: 0.4em;}
main.js
(version jQuery):
$(document).ready(function() {
$("button").click(function() {
["object", "iframe", "embed", "img"].forEach(function(elmtType) {
var $e, $threeElmts = $(elmtType);
$e = $($threeElmts[0]);
if ($e[0].contentDocument) $e.replaceWith($($e[0].contentDocument.documentElement).clone());
$e = $($threeElmts[1]);
if ($e[0].getSVGDocument) $e.replaceWith($($e[0].getSVGDocument().documentElement).clone());
$e = $($threeElmts[2]);
$.get($e.attr($e.prop("nodeName") === "OBJECT" ? "data" : "src"), function(data) {
$e.replaceWith(data.documentElement);
});
});
});
});
main.js
(version JavaScript vanille):
document.addEventListener("DOMContentLoaded", function() {
document.querySelector("button").addEventListener("click", function() {
["object", "iframe", "embed", "img"].forEach(function(elmtType) {
var e, threeElmts = document.querySelectorAll(elmtType);
e = threeElmts[0];
if (e.contentDocument) e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true), e);
e = threeElmts[1];
if (e.getSVGDocument) e.parentElement.replaceChild(e.getSVGDocument().documentElement.cloneNode(true), e);
e = threeElmts[2];
var xhr = new XMLHttpRequest();
xhr.open("GET", e.getAttribute(e.nodeName === "OBJECT" ? "data" : "src"));
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) e.outerHTML = xhr.responseText;
};
});
});
});
id
et class
(ou tout autre), écouteurs d'événements, fonctionnalité iframe
, etc.object
, iframe
, embed
et img
. Il ne traite pas des images SVG externes référencées dans les propriétés CSS background-image
Ou dans la fonction drawImage
d'un contexte <canvas>
. Je soupçonne que cela ne fonctionnera pas de cette façon, mais je n'ai pas vérifié.index.html
, Chrome et Opera ont des paramètres de sécurité cela rendra cela impossible. Pour que ces navigateurs fonctionnent dans une telle configuration locale, vous devez plutôt exécuter un serveur local comme indiqué dans cette autre SO question . Il ne devrait pas y avoir de problème si vous utilisez la stratégie d'inline dans un site Web hébergé par un serveur normal.Il s'agit de la procédure pas à pas la plus complète (1) des différentes façons d'utiliser les SVG dans votre HTML et (2) de la manière dont vous pouvez faire le style des pièces individuelles (c.-à-d. Les chemins) du SVG via CSS/JS.
https://css-tricks.com/using-svg/
Dans une balise d'image (par exemple: <img src="picture.svg" />
ou comme image d'arrière-plan en CSS = pas de style
Inline - style loin, mais il encombrera votre HTML. PHP aide ici, ou vous pouvez utiliser une tâche de compilation gulp ou quelque chose pour empêcher les SVG d'encombrer votre code de travail, tout en restant en ligne à la fin.
En tant qu'objet, vous pouvez maintenant ajouter CSS dans le fichier .svg:
<svg ...>
<style>
/* SVG specific fancy CSS styling here */
</style>
...
</svg>
ou
<?xml-stylesheet type="text/css" href="svg.css" ?>
URI de données - peut être idéal pour les images d'arrière-plan. Pas de style.