我们有一个图标库,我们会在文档的底部进行内联,例如
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon1" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="green"/>
</symbol>
<symbol id="icon2" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="red"/>
</symbol>
</svg>
在我们需要的任何地方都可以简单地引用这些图标,例如
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="16px" height="16px">
<use xlink:href="#icon1"/>
</svg>
现在有时我们需要使用图标作为背景图像,类似于
<div style="width:16px; height:16px; background-size:cover; background-image: url(//placehold.it/16x16)"></div>
可以使用data:image/svg+xml
数据URIS使用SVG作为背景图像,如下所述:
<div style='width:16px; height:16px; background-size:cover; background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="0" y="0" width="100" height="100" fill="red"/></svg>')'></div>
但是,从数据内部引用ID uri内部的ID并不能以相同的方式工作:
<h3>referenced in <code>svg</code></h3>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="16px" height="16px">
<use xlink:href="#icon"/>
</svg>
<h3>referenced in <code>background-image</code>
<div style="width:16px; height:16px; background-size:cover; background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 100 100'><use xlink:href='#icon'/></svg>")"></div>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="red"/>
</symbol>
</svg>
我假设data:image/svg+xml
为文档创建了一个新的"上下文",因此#icon
是指data:image/svg+xml
中的一个节点(因为它在原始文档中,因为它不存在(。
有没有一种方法来引用原始文档(例如,与Shadow dom api中的ShadowRoot.host
相似的内容(?(也许类似xlink:href=":host#icon"
(
我想到的唯一解决方法是使用JavaScript来嵌入使用的符号:
Array.from(document.querySelectorAll('[style*="data:image/svg+xml;utf8,"]'))
.forEach(function(e) {
e.style.backgroundImage = getComputedStyle(e).backgroundImage.replace(
/<use xlink:href='#([^']+)'/>/g,
function(match, id) {
return document.getElementById(id).innerHTML.replace(/(^s*|s*$)/g, '').replace(/"/g, "'")
}
)
})
<h3>referenced in <code>background-image</code> with JS inlining</h3>
<div style="width: 16px; height: 16px; background-size: cover; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 100 100'><use xlink:href='#icon'/></svg>")"></div>
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon" viewBox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="red"/>
</symbol>
</svg>
但我真的希望完全避免JavaScript。
这是一个常见问题的微妙变化。
是否有一种方法来引用原始文档
答案是 no 。任何文件(其中包括以数据URL的形式(加载为<img>
或background-image
等的文件,都需要自行包含。它们被加载为独立对象,无法引用其他文件。
您需要将<symbol>
包括在数据URL中。