听起来您可能有四个问题:
- 如何将脚本嵌入 SVG 文件中?
- 如何在 SVG 文件中运行脚本?
- 我如何访问数据
<path>
脚本中的元素?
- 我如何操作数据
<path>
脚本中的元素?
让我们一次解决一个问题:
如何将脚本嵌入 SVG 文件中?
如中所述SVG 规范 http://www.w3.org/TR/SVG/script.html#ScriptElement你可以放置一个<script>
文档中包含 JavaScript 代码的元素。根据最新的SVG规范,你不需要指定type属性 http://www.w3.org/TR/SVG/script.html#ScriptElementTypeAttribute为你的脚本。它将默认为type="application/ecmascript"
.
- 其他常见的哑剧类型包括
"text/javascript"
, "text/ecmascript"
(在 SVG 1.1 中指定),"application/javascript"
, and "application/x-javascript"
。我没有有关所有这些浏览器支持的详细信息,或者省略了type
属性一并。我一直都取得了很好的成功text/javascript
.
与 HTML 一样,您可以将脚本代码直接放入文档中,也可以引用外部文件。当执行后者时,您必须使用href
属性(不src
) 对于 URI,属性位于xlink
命名空间。
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script xlink:href="/js/mycode.js" />
<script><![CDATA[
// Wrap the script in CDATA since SVG is XML and you want to be able to write
// for (var i=0; i<10; ++i )
// instead of having to write
// for (var i=0; i<10; ++i )
]]></script>
</svg>
如何在 SVG 文件中运行脚本?
与 HTML 一样,SVG 文档中包含的代码一遇到就会运行。如果您将您的<script>
元素位于文档其余部分之上(就像您将<script>
in the <head>
HTML 文档),那么当您的代码运行时,您的文档元素将不可用。
避免这种情况的最简单方法是将您的<script>
文档底部的元素:
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- all SVG content here, above the script -->
<script><![CDATA[
// Now I can access the full DOM of my document
]]></script>
</svg>
或者,您可以在文档顶部创建一个回调函数,仅当文档的其余部分准备就绪时才调用该函数:
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<title>SVG Coordinates for Embedded XHTML Elements</title>
<script>document.documentElement.addEventListener('load',function(){
// This code runs once the 'onload' event fires on the root SVG element
console.log( document.getElementById('foo') );
},false)</script>
<path id="foo" d="M0 0" />
</svg>
我如何访问数据<path>
脚本中的元素?
有两种方法可以访问有关 SVG 中元素的大部分信息:您可以通过标准 DOM Level 1 Core 方法以字符串形式访问属性getAttribute() http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core.html#method-getAttribute,或者您可以使用SVG DOM 对象和方法 http://www.w3.org/TR/SVG/svgdom.html。让我们看看两者:
通过以下方式访问路径数据getAttribute()
Using getAttribute()
返回与查看源代码时看到的相同的字符串:
<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
var data = path.getAttribute('d');
console.log(data);
//-> "M150 0 L75 200 L225 200 Z"
]]></script>
- 优点:调用非常简单;你不必了解任何有关 SVG DOM 的知识
- 缺点:既然你返回一个字符串,你必须自己解析该属性;对于 SVG
<path>
数据,这可能会令人痛苦。
通过 SVG DOM 方法访问路径数据
<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
// http://www.w3.org/TR/SVG/paths.html#__svg__SVGAnimatedPathData__normalizedPathSegList
// See also path.pathSegList and path.animatedPathSegList and path.animatedNormalizedPathSegList
var segments = path.normalizedPathSegList ;
for (var i=0,len=segments.numberOfItems;i<len;++i){
var pathSeg = segments.getItem(i);
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSeg
switch(pathSeg.pathSegType){
case SVGPathSeg.PATHSEG_MOVETO_ABS:
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegMovetoAbs
console.log("Move to",pathSeg.x,pathSeg.y);
break;
case SVGPathSeg.PATHSEG_LINETO_ABS:
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegLinetoAbs
console.log("Line to",pathSeg.x,pathSeg.y);
break;
case SVGPathSeg.PATHSEG_CLOSEPATH:
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegClosePath
console.log("Close Path");
break;
}
}
]]></script>
上述脚本产生以下输出:
Move to 150 0
Line to 75 200
Line to 225 200
Close Path
因为阅读 SVG DOM 的 W3C 规范可能很困难,所以很多年前我创建了一个在线工具来浏览存在的属性和对象。您可以在这里使用它:http://objjob.phrogz.net/svg/hierarchy http://objjob.phrogz.net/svg/hierarchy
我如何操作数据<path>
脚本中的元素
与上面类似,您可以创建一个新字符串并使用setAttribute()
将其推到对象上,或者您可以操作 SVG DOM。
使用操作路径数据setAttribute()
<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
path.setAttribute('d','M150,0 L150,100 200,300 Z');
]]></script>
使用 SVG DOM 操作路径数据
<path id="foo" d="M150,0 L75,200 l150,0 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
var segments = path.pathSegList;
segments.getItem(2).y = -10;
]]></script>
一般来说,只需要修改各个属性即可SVGPathSeg
子类实例;更改会立即在 DOM 中进行。 (在上面的示例中,随着最后一个点稍微向上移动,原始三角形发生了倾斜。)
当你需要创建新的路径段时,你需要使用类似的方法var newSegment = myPath.createSVGPathSegArcAbs(100,200,10,10,Math.PI/2,true,false) http://www.w3.org/TR/SVG/paths.html#__svg__SVGPathElement__createSVGPathSegArcAbs然后使用其中一种方法将此段粘贴到列表中,例如segments.appendItem(newSegment) http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegList.