问题描述
我有一个页面,我有一个按钮可将所有< svg>
导出到一个.svg文件中。
问题在于代码只输出< svg>
之一。
我可以在inkscape上打开它,但只能得到其中一个svg。
我无法在浏览器上打开它,我收到一条错误消息。
我无法在illustrator上打开,我收到一条错误消息,指出该文件已损坏或类似。
这里是我使用的代码:
<!DOCTYPE html>< html xmlns =http:// www .w3.org / 1999 / xhtml>< head>< meta charset =UTF-8>< script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1 .1 / jquery.min.js>< / script>< script src =svg-converter.js>< / script>< scri pt> jQuery(document).ready(function($){$('。svg-convert')。svgConvert({onComplete:function(){exportSVG(document.getElementById('mySVG')); }});});< / script>< style> #mySVG> svg {width:40%; float:left;}< / style>< / head>< body> < main id =content> < div id =mySVGxmlns =http://www.w3.org/3000/svgxmlns:xlink =http://www.w3.org/1999/xlink> < img src ='https://cdn.kastatic.org/images/avatars/svg/leafers-sapling.svg'class ='svg-convert'> < img src ='https://cdn.kastatic.org/images/avatars/svg/aqualine-sapling.svg'class ='svg-convert'> < / DIV> < / main><! - #main - > <脚本> var exportSVG = function(svg){//首先创建我们的svg节点的一个克隆,这样我们就不会混淆原始的一个var clone = svg.cloneNode(true); //解析样式parseStyles(clone); //获取数据var svgData = document.getElementById('mySVG')。innerHTML; //这里我将简单地通过下载属性var a = document.createElement('a'); a.href ='data:image / svg + xml; charset = utf8,'+ encodeURIComponent(svgData.replace(/>< / g,'> \\\
\r<')); a.download ='finalSVG.svg'; a.innerHTML ='下载.SVG文件'; document.body.appendChild(一); }; var parseStyles = function(svg){var styleSheets = []; var i; //获取文档样式表(如果svg位于< iframe>或< object>时,ownerDocument)var docStyles = svg.ownerDocument.styleSheets; //将实时StyleSheetList转换为数组以避免无限循环(i = 0; i< docStyles.length; i ++){styleSheets.push(docStyles [i]); } if(!styleSheets.length){return; } var defs = svg.querySelector('defs')|| document.createElementNS('http://www.w3.org/2000/svg','defs'); if(!defs.parentNode){svg.insertBefore(defs,svg.firstElementChild); } svg.matches = svg.matches || svg.webkitMatchesSelector || svg.mozMatchesSelector || svg.msMatchesSelector || svg.oMatchesSelector; //遍历所有文档的样式表for(i = 0; i< styleSheets.length; i ++){var currentStyle = styleSheets [i] var rules;尝试{rules = currentStyle.cssRules; } catch(e){continue; } //创建一个新的样式元素var style = document.createElement('style'); //一些样式表不能被访问并且会引发安全错误var l = rules&& rules.length; //遍历这个样式表的每个cssRules for(var j = 0; j< l; j ++){//得到这个cssRules的选择器var selector = rules [j] .selectorText; //可能是我们无法访问的外部样式表if(!selector){continue; } //是我们的svg节点还是它的一个子节点?如果((svg.matches& svg.matches(selector))|| svg.querySelector(selector)){var cssText = rules [j] .cssText; //将它追加到我们的< style>节点style.innerHTML + = cssText +'\\\
';如果我们有一些规则if(style.innerHTML){//将样式节点追加到克隆的defs defs.appendChild(style); }}}; < / script>< / html>
p>我正在使用SVG转换()在页面加载之前从.SVG转换为< svg>
。这部分工作,没有问题。
在这里你可以看到代码运行:
嵌套< svg>
在另一个< svg>
内不起作用,因为它们没有嵌套。我不知道它是否因为svgConvert,但它们简单地打印在'父'之外< svg>
。
- 它包含两个
< svg>
标签并排,这是无效的SVG(也不是XML)
-
< svg>
标签没有名称空间,而它们应该有一个http://www.w3.org/2000/svg
命名空间遵守标准
第一个问题必须在JS中计算出来,而第二个问题可以通过指定<$ c您的库调用的$ c> svgCleanupAttr 选项:
jQuery(document).ready(function $($。$ s $ $ $ $''svg-convert')。svgConvert({
onComplete:function(){
exportSVG(document.getElementById('mySVG'));
},
svgCleanupAttr:[]
});
});
var exportSVG = function(divContainer){
//首先创建一个我们svg节点的克隆,这样我们就不会混淆原始的
var svgContainer = document.createElementNS( http://www.w3.org/2000/svg,svg);
$(divContainer).find(svg)。clone()。appendTo(svgContainer);
//解析样式
// parseStyles(svgContainer);我现在不打扰它
//获取数据
var svgData = svgContainer.outerHTML;
//在这里,我将简单地通过下载属性
var a = document.createElement('a');
a.href ='data:image / svg + xml; charset = utf8,'+ encodeURIComponent(svgData);
a.download ='finalSVG.svg';
a.innerHTML ='下载.SVG文件';
document.body.appendChild(a);
};
您可以尝试。我已经移除了这里不需要的 parseStyle
函数,如果需要的话将其添加回去。
请注意,由此导致的svg并不完美,因为根标签没有命名空间。它仍然可以正确显示在我的Chrome上。
I have a page where I have a button to export all the <svg>
into one single .svg file.
The problem is that the code is only exporting one of the <svg>
.
I can open it on inkscape, but only get one of the svg inside.
I can't open it on my browser, I get an error message.
I can't open on illustrator, I get an error message that the file is corrupted or something like that.
Here is the code I'm using:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="svg-converter.js"></script>
<script>
jQuery(document).ready(function($) {
$('.svg-convert').svgConvert({
onComplete: function() {
exportSVG(document.getElementById('mySVG'));
}
});
});
</script>
<style>
#mySVG > svg{
width: 40%;
float: left;
}
</style>
</head>
<body>
<main id="content">
<div id="mySVG" xmlns="http://www.w3.org/3000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<img src='https://cdn.kastatic.org/images/avatars/svg/leafers-sapling.svg' class='svg-convert'>
<img src='https://cdn.kastatic.org/images/avatars/svg/aqualine-sapling.svg' class='svg-convert'>
</div>
</main><!-- #main -->
<script>
var exportSVG = function(svg) {
// first create a clone of our svg node so we don't mess the original one
var clone = svg.cloneNode(true);
// parse the styles
parseStyles(clone);
// get the data
var svgData = document.getElementById('mySVG').innerHTML;
// here I'll just make a simple a with download attribute
var a = document.createElement('a');
a.href = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData.replace(/></g, '>\n\r<'));
a.download = 'finalSVG.svg';
a.innerHTML = 'download the .SVG file';
document.body.appendChild(a);
};
var parseStyles = function(svg) {
var styleSheets = [];
var i;
// get the stylesheets of the document (ownerDocument in case svg is in <iframe> or <object>)
var docStyles = svg.ownerDocument.styleSheets;
// transform the live StyleSheetList to an array to avoid endless loop
for (i = 0; i < docStyles.length; i++) {
styleSheets.push(docStyles[i]);
}
if (!styleSheets.length) {
return;
}
var defs = svg.querySelector('defs') || document.createElementNS('http://www.w3.org/2000/svg', 'defs');
if (!defs.parentNode) {
svg.insertBefore(defs, svg.firstElementChild);
}
svg.matches = svg.matches || svg.webkitMatchesSelector || svg.mozMatchesSelector || svg.msMatchesSelector || svg.oMatchesSelector;
// iterate through all document's stylesheets
for (i = 0; i < styleSheets.length; i++) {
var currentStyle = styleSheets[i]
var rules;
try {
rules = currentStyle.cssRules;
} catch (e) {
continue;
}
// create a new style element
var style = document.createElement('style');
// some stylesheets can't be accessed and will throw a security error
var l = rules && rules.length;
// iterate through each cssRules of this stylesheet
for (var j = 0; j < l; j++) {
// get the selector of this cssRules
var selector = rules[j].selectorText;
// probably an external stylesheet we can't access
if (!selector) {
continue;
}
// is it our svg node or one of its children ?
if ((svg.matches && svg.matches(selector)) || svg.querySelector(selector)) {
var cssText = rules[j].cssText;
// append it to our <style> node
style.innerHTML += cssText + '\n';
}
}
// if we got some rules
if (style.innerHTML) {
// append the style node to the clone's defs
defs.appendChild(style);
}
}
};
</script>
</body>
</html>
I'm using SVG Convert (https://github.com/madebyshape/svg-convert) to convert from .SVG to <svg>
before the page loads. That part works, no problem there.
Here you can see the code runing: http://brand.express/projects/teste/index4.php
Nesting the <svg>
inside another <svg>
doesn't work because they don't get nested. I don't know if its because of the svgConvert, but they simple are printed outside the 'father' <svg>
.
Currently the file available for download has two problems :
- it contains two
<svg>
tags side-by-side, which isn't valid SVG (nor XML) - the
<svg>
tags have no namespace, while they should have ahttp://www.w3.org/2000/svg
namespace to respect the standards
The first problem must be worked out in your JS, while the second can be fixed by specifying the svgCleanupAttr
option of your library call:
jQuery(document).ready(function($) {
$('.svg-convert').svgConvert({
onComplete: function() {
exportSVG(document.getElementById('mySVG'));
},
svgCleanupAttr: []
});
});
var exportSVG = function(divContainer) {
// first create a clone of our svg node so we don't mess the original one
var svgContainer = document.createElementNS("http://www.w3.org/2000/svg", "svg");
$(divContainer).find("svg").clone().appendTo(svgContainer);
// parse the styles
//parseStyles(svgContainer); I didn't bother with it for now
// get the data
var svgData = svgContainer.outerHTML;
// here I'll just make a simple a with download attribute
var a = document.createElement('a');
a.href = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
a.download = 'finalSVG.svg';
a.innerHTML = 'download the .SVG file';
document.body.appendChild(a);
};
You can try it here. I've removed the parseStyle
function which wasn't needed here, add it back if necessary.
Note that the resulting svg isn't perfect, for some reason the root tag has no namespace. It was still correctly displayed by my Chrome.
这篇关于合并2< svg>成一个.SVG文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!