我正在尝试使用'innerHTML'从外部文件中注入SVG渐变定义,以保持HTML清洁。
它适用于Chrome,但不适用于Safari或Mobile Safari。 任何想法或解决方法?
这是一个简化的例子(注入的第二个渐变,实际上是从服务器请求html):
<html>
<body>
<svg width="0" height="0">
<defs>
<linearGradient id="grad1" x2="0" y2="1"> <stop offset="0" stop-color="#ffff00"/><stop offset="1" stop-color="#ff0000"/> </linearGradient>
</defs>
</svg>
<svg width="0" height="0" id="svg-grad"></svg>
<script>
function inject_svg() {
var gr2=document.getElementById('svg-grad');
html='<defs><linearGradient id="grad2"><stop offset="0" stop-color="#ffff00"/><stop offset="1" stop-color="#ff0000"/> </linearGradient></defs>';
gr2.innerHTML=html;
}
</script>
<svg width="200" height="200">
<rect fill="url(#grad1)" x="20" y="20" width="50" height="150"/>
<rect fill="url(#grad2)" x="100" y="20" width="50" height="150"/>
</svg>
<button onclick="inject_svg();">inject</button>
</body>
</html>
在jsfiddle:http://jsfiddle.net/wPL4n/
答案 0 :(得分:3)
它可能在html命名空间而不是SVG命名空间中添加内容。尝试使用DOMParser,并为数据设置显式命名空间(即xmlns =&#34; http://www.w3.org/2000/svg"在数据的根元素上)。
<svg width="0" height="0" id="svg-grad"></svg>
<script>
function inject_svg() {
var gr2=document.getElementById('svg-grad');
html='<defs xmlns="http://www.w3.org/2000/svg"><linearGradient id="grad2"><stop offset="0" stop-color="#ffff00"/><stop offset="1" stop-color="#ff0000"/> </linearGradient></defs>';
var xmlDoc = new DOMParser().parseFromString(html, "text/xml");
gr2.appendChild(xmlDoc.documentElement);
}
</script>
<svg width="200" height="200">
<rect fill="url(#grad1)" x="20" y="20" width="50" height="150"/>
<rect fill="url(#grad2)" x="100" y="20" width="50" height="150"/>
</svg>
<button onclick="inject_svg();">inject</button>
答案 1 :(得分:1)
您可以使用innersvg.js polyfill
。
基于webkit bug跟踪器:https://bugs.webkit.org/show_bug.cgi?id=136903,此问题是由DOM规范的不同实现引起的;具体而言,innerHTML/outerHTML
在HTMLElement
上定义,SVGElement
不是子类。
2014-12-02:这个问题应该修复:)
修补程序r176630更改了该行为,并将定义向上移动了一个级别,以便可以在HTMLElement
和SVGElement
之间共享它们,并使其行为更接近竞争的浏览器/呈现引擎。< / p>
如果你居住在边缘,你可以获得new nightly build,例如webkit r176637(注意:我还没试过)。