在 HTML 中包含 SVG 文件,并且仍然能够对它们应用样式? [英] Include SVG files with HTML, and still be able to apply styles to them?
问题描述
您可以通过 embed
object
和 svg
标签将 SVG 文件包含到您的 HTML 文件中.
- 使用
embed
或object
标签需要将图像与 URL 链接.(这是我更喜欢的,因为我不喜欢 HTML 代码中的所有 SVG 代码,所以我想保持这种方式.) - 使用
svg
标签 (AFAIK) 需要在 HTML 代码中内嵌 SVG 代码.
我的问题是:
如何将 SVG 图标、图像和其他文件包含到我的 HTML 文件中,而不必将整个 SVG 代码放入其中,并且仍然能够对其应用样式?通过 JS 应用它们也可以.
注意:
当我通过 object
或 embed
包含它们时,我似乎无法通过 jQuery 访问它们,即使使用 $("#my-svg-div").find("svg")
(顺便说一下,几乎所有关于 SO 的答案都说我应该这样做).我只是得到 undefined
.
谢谢!
简答
您可以通过编程方式内联 SVG 图像.这样的图像可以与实际的内联 <svg>
元素基本相同,包括能够对其应用样式.
如果您的 SVG 图像在 或
元素 (
e
) 中被引用,您可以将其内联如下:
e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true), e);
如果您的 SVG 图像在 <embed>
元素中被引用,请将上述代码中的 .contentDocument
替换为 .getSVGDocument()
.
如果您的 SVG 图像在 <img>
元素中被引用,则可以使用一种完全不同的策略(包括 AJAX 和下文所述)来内联图像.
总体战略
如果您的外部 SVG 图像文件是同源的(例如,图像是从与 HTML 代码相同的位置加载的),则允许对这些图像进行样式设置的一种方法是以编程方式内联它们,如下所示:
- 检索外部 SVG 文件的内容.
- 将该内容直接添加回与原始引用元素相同的 HTML DOM 位置中的 HTML 文件,即内嵌".
- 删除最初引用外部 SVG 文件的元素.
好处
这种内联策略为您提供了两全其美的好处:
您可以获得单独图像文件的好处,包括:
- 独立于 HTML 组织您的图像文件,
- 保持原始 HTML 文件与图像详细信息保持一致,并且
- (可能)允许浏览器缓存图像(但请参阅下面关于最后一点的内容).
然而,您仍然可以对最终内联的 SVG 图像执行任何操作,而您可以对真正最初内联的
<svg>
元素执行任何操作,包括:- 对它们应用 CSS 样式,
- 将事件侦听器应用于单个 SVG 形状或组等.
实施
对于
或
元素:
您可以按如下方式内联外部引用的 SVG 代码:
//使用 vanilla JavaScript(如上所示):e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true), e);//使用 jQuery:$e.replaceWith($($e[0].contentDocument.documentElement).clone());
...其中 e
或 $e
是 vanilla 或 jQuery 变量(分别),您在其中选择了外部 SVG 引用 <object>
或 元素.
要包含
元素:
如果您使用的是引用外部 SVG 的 <embed>
元素,那么您可以通过替换上面的 .contentDocument
来内联 SVG 内容带有 .getSVGDocument()
的代码(注意附加括号).请注意,.contentDocument
不适用于 元素,而
.getSVGDocument()
实际上适用于所有三种元素类型.但是 .getSVGDocument()
点击按钮后,尝试内联,现在屏幕看起来像这样.CSS 样式已成功应用于某些元素:
此示例所需的代码如下:
image.svg
(外部引用的文件,即未嵌入 HTML):
index.html
(显然,如果不使用 jQuery,请删除 jQuery 脚本行):
<头><link href="styles.css" rel="stylesheet"><script src="//code.jquery.com/jquery-1.12.0.min.js"></script><script src="main.js"></script>头部><身体><button>单击以尝试内嵌 svg 图像.</button><表格><tr><th></th><th>svg </th><th>对象</th><th>iframe</th><th>嵌入</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/>(不推荐使用)</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>