Javascript 包含带有HTML的SVG文件,并且仍然能够对其应用样式?
您可以通过Javascript 包含带有HTML的SVG文件,并且仍然能够对其应用样式?,javascript,jquery,html,css,svg,Javascript,Jquery,Html,Css,Svg,您可以通过embedobject和SVG标记将SVG文件包含到HTML文件中 使用嵌入或对象标记需要将图像与URL链接。(这是我喜欢的,因为我不喜欢HTML代码中的所有SVG代码,所以我希望保持这种方式。) 使用svg标记(AFAIK)需要将svg代码内联到HTML代码中 我的问题是: 我如何将SVG图标、图像和其他文件包含到HTML文件中,而不必将整个SVG代码放入其中,并且仍然能够对它们应用样式?通过JS应用它们也很好 注: 当我通过object或embed包含它们时,我似乎无法通过jQ
embed
object
和SVG
标记将SVG文件包含到HTML文件中
- 使用
或嵌入
标记需要将图像与URL链接。(这是我喜欢的,因为我不喜欢HTML代码中的所有SVG代码,所以我希望保持这种方式。)对象
- 使用
标记(AFAIK)需要将svg代码内联到HTML代码中svg
object
或embed
包含它们时,我似乎无法通过jQuery访问它们,即使使用$(“#我的svg div”)。查找(“svg”)
(顺便说一句,几乎每个答案都说我应该这样做)。我只是得到了未定义的
谢谢大家! 这是最全面的演练,(1)在HTML中使用SVG的不同方式,(2)通过CSS/JS可以对SVG的各个部分(即路径)进行样式化
在图像标签中(即:
或作为CSS中的背景图像=无样式
内联样式,但它会使您的HTML.PHP变得混乱,或者您可以使用一个gulp构建任务或其他方法来防止SVG在最后仍然内联的情况下使您的工作代码变得混乱
作为一个对象,您现在可以在.svg文件中添加CSS:
<svg ...>
<style>
/* SVG specific fancy CSS styling here */
</style>
...
</svg>
/*这里是SVG特有的花式CSS样式*/
...
或
数据URI-可以很好地用于背景图像。没有样式
简短回答
您可以通过编程方式内联SVG图像。这样的图像本质上可以与实际的内联
元素相同,包括能够对其应用样式
如果在
或
元素(e
)中引用了SVG图像,则可以按如下方式将其内联:
e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true),e);
如果在
元素中引用了SVG图像,请将上述代码中的.contentDocument
替换为.getSVGDocument()
如果SVG图像在
的属性、
和
元素的属性中引用,但在
元素的数据属性中引用。此策略可按如下方式实现:
例子
下面的示例演示了上述策略是否允许将外部CSS样式应用于最初的外部SVG图像。(由于需要引用本地外部文件,我没有创建代码片段或JSFIDLE。)
以下两个屏幕截图显示了内联前后的CSS样式(红色三角形)或缺少CSS样式(黑色三角形)。它显示了最初嵌入HTML(
)或在指示元素(
,
,
和
)中引用的SVG图像的结果.三行显示使用三种指定策略进行内联的结果
在单击按钮之前,尚未尝试内联,屏幕如下所示。仅对嵌入的SVG元素(第1列)进行样式设置:
单击按钮后,将尝试内联,屏幕显示如下。CSS样式已成功应用于某些元素:
此示例所需的代码如下所示:
image.svg
(外部引用文件,即未嵌入HTML中):
style.css
(只有多边形
行对于演示内联非常重要):
main.js
(jQuery版本):
main.js
(普通JavaScript版本):
注意以下几点:
- 此策略将要求您处理与原始引用元素相关的任何特征,例如回退图像、
id
和class
(或任何其他)属性、事件侦听器、iframe
功能等
- 确保仅在实际加载图像文件后才尝试内联
- 考虑在服务器端内联以允许服务单个文件,但在客户端内联以允许图像文件缓存
- 我在Firefox 44.0、Chrome 49.0和Opera 35.0(Mac和Windows)、Safari 9.0(Mac)和IE 11(Windows)中验证了这一策略。我没有检查Edge或任何移动浏览器
- 此解决方案解决了从
对象
、iframe
、嵌入
和img
元素引用SVG文件的问题。它不解决CSS背景图像
属性或
上下文的drawImage
函数中引用的外部SVG图像。我怀疑这些不会起作用是的,但我还没查过
- 如果您试图在本地计算机上复制示例代码,方法是复制并保存代码,然后“打开”在ing
index.html
中,Chrome和Opera的安全设置将使这一点变得不可能。要使这些浏览器在这样的本地配置中工作,您需要按照中的说明运行本地服务器。如果您在普通服务器托管的网站中使用内联策略,则应该不会出现此类问题
基本上……你不能……很容易——好吧……所以我假设能够访问SVG的dashArrayOffset,意味着我也能够访问样式。我有一个object标记,这个插件能够绘制SVG的笔划,即使它是一个对象而不是SVG。我现在正在看代码。。。
<?xml-stylesheet type="text/css" href="svg.css" ?>
// using vanilla JavaScript (as shown above):
e.parentElement.replaceChild(e.contentDocument.documentElement.cloneNode(true), e);
// using jQuery:
$e.replaceWith($($e[0].contentDocument.documentElement).clone());
// 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);
});
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px">
<polygon points="25,5 45,45 5,45 25,5"/>
</svg>
<!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>
polygon {fill: red;}
table {border-collapse: collapse;}
td, th {border: solid black 1px; padding: 0.4em;}
$(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);
});
});
});
});
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;
};
});
});
});