可移植的SVG文档

   
可移植的SVG文档
修订记录:
2006-11-2 : 增加了浏览器对XML, XMLHTTP,空白节点以及其它细节不同处理方式的描述。
可移植的SVG文档_第1张图片
 
      
      
目前SVG实现基本上是SVG1.1,主要有:
n         ADOBE SVG VIEWER(PLUGIN)  (ASV,在2009/1/1停止下载)
n         BATIK 1.6 (基于JAVA的SVG开发工具 )
n         MOZILLA FIREFOX 1.5 (FF) 
n         OPERA 8/9
 
不同的实现对标准的覆盖有所不同,目前ASV和OPERA9对SVG1.1的实现比较全,FF和BATIK的覆盖较少(仅仅是目前的情况,随时可能变化)。各SVG实现或多或少都存在对标准的扩展,例如ASV中的很多get/set函数。在SVG编程告诫中提出了很多有效的方法以保证SVG的移植性,本文主要讨论ASV到FF的移植问题,可以看做一种解释和补充。ASV目前的使用比较多,对SVG的要求不很严格,而且本身的非标准扩展也比较多。 在2009年一月停止下载后,很多在ASV下开发的SVG程序要面临移植的问题,因此也必须要了解这些方法。
 
1,SVG必须包含SVG名字空间声明
<svg xmlns="http://www.w3.org/2000/svg" onload="init(evt)">
ASV对此不做要求,但没有名字空间声明的SVG文档在FF下无法显示
 
2.使用初始化事件得到SVG文档对象和根元素对象
       var svgDocument = null;
   var svgRoot = null;
       function init(evt)
       {
              svgDocument = evt.target.ownerDocument;
        svgRoot = svgDocument.documentElement;
       }
       ASV中可以使用缺省的document和SVGDocument对象,但FF中必须自行取得SVG文档对象。
 
3.不使用ASV的扩展getter和setter方法,例如evt.getTarget()实际上DOM和SVG规范定义的是属性,而不是方法,因此正确的写法应为evt.target
 
此外还包括
evt.getOwnerDocument() => evt. ownerDocument
evt.getDocumentElement() => evt. ocumentElement
evt.getType() => evt.type
evt.getCharCode() => evt.charCode
evt.getKeyCode() => evt.keyCode
evt.getTarget() => evt.target
evt.getScreenX() => evt.screenX
evt.getClientX() => evt.clientX
 
elem.getData() => elem.data
elem.setData() => elem.data
node.getFirstChild() => node.firstChild
node.getChildNodes() => node.childNodes
 
最好对get和set全部搜索一遍,对有疑点的函数全部替换为数据访问方式。
 
4.不使用动画等FIREFOX和OPERA目前不支持的特性,而是使用自己的脚本,或第三方的模拟实现SMIL的JAVASCRIPT脚本库。下载地址为:
http://www.vectoreal.com/smilscript/
 
5.这个问题是浏览器的问题,而不是SVG的问题,但在SVG中经常要使用到XML,而且如果使用AJAX也会使用到XMLHTTP方法,所以也列在这里。对XML和XMLHTTP的使用,IE与FF等有所不同,IE通过ACTIVEX操作XML,而FF使用内置控件,双方对XPATH的实现也有所不同,如果我们使用XMLHttpRequest方法,浏览器的行为也有所不同,除了其实现方法,还有安全设置的问题。例如,如果页面保存在用户本地的机器上,IE浏览器打开这个页面时,缺省情况下可以访问所有的域,而在Firefox浏览器中做这件事情要稍微麻烦一点,需要请求相应的权限。
在实现时,最好使用ZXML库实现对XML的操作。ZXML是封装各种浏览器XML操作的脚本库,下载地址在: http://www.nczonline.net/downloads/。使用ZXML仅仅能够部分解决这个问题,要实现真正的跨浏览器使用,还有对其使用方式加以控制。下面为几个例子:
 
l         在IE中,本地的页面可以访问访问所有的域,因此,下面的代码可以运行。
l          
var url = "http://blog.csdn.net/firefight/Rss.aspx";
oXmlHttp.open("get",url, true);
 
而在FF中open函数会产生权限不足的错误。
 
l         IE6不支持getElementByTagNameNS,对带有名字空间的Element,IE可以用以下方式访问:
 
var commentTimes = nodes[count].getElementsByTagName("slash:comments");
 
而FF中必须使用:
 
var slashNS = "http://purl.org/rss/1.0/modules/slash/";
var commentTimes = nodes[count].getElementsByTagNameNS(slashNS,"comments");
 
l         对节点列表nodelist,不要使用item属性,FF不支持该访问方法
l          
nodes.item(i) => nodes[i]
 
l         对空白节点的处理,各种XML实现之间也有所不同。使用XPATH得到的一个单独的节点,然后使用nextSibling和previousSibling遍历时,FF计算空白节点,但在IE中不计算,因此对于带换行的XML节点,例如
 
<store>
    <book id=”1”/>
    <book id=”2”/>
</store>
 
FF中使用XPATH 路径/store/book[1]取得的节点为id为1的book节点,此时IE中也一样,但在使用nextSibling后,FF中指向两个book之间的空白节点,而IE中指向了id为2的book。因此还是使用getElementsByTagName比较保险,或使用selectNodes得到节点列表,然后在列表中使用索引遍历也可以避免这个问题。例如:
 
this.questionList = zXPath.selectNodes(this.dom.documentElement, "/Quiz/Question");
this.totalCount = this.questionList.length;
this.currentNode = this.questionList[this.currentIndex];
 
仅仅通过XPATH得到节点,然后使用nextSibling和previousSibling必须检查节点的名称,以避免空白节点。建议在任何情况下都对节点名称的类型进行检查,因为这种错误与外部的XML数据相关,在编程时使用的XML可能不会有问题,而在实际部署后由于数据格式(换行)引起错误,而且比较难发现。
 
6,回调函数中的类成员使用
在IE中,嵌入式的回调函数可以使用当前类实例中的数据和成员函数,而FF中只能访问到类数据,无法访问成员函数。
 
7,一些实现细节的不同,这是最烦人的。很多问题是由于不同SVG实现之间的很小的差别引起,很难查找,如果不是在开发时一步步进行调试,这个过程就比较痛苦了。这里仅仅列出一部分曾经遇到的问题:
 
l         间断线
       ASV间断线属性各数值之间可以使用空格,而FF必须使用“,”作为分隔符。例如stroke-dasharray="5,5,10,10"
      
l         路径
       ASV对路径中下一个点的缺省连接方式为L,而FF必须指明到下一个路径的方法,例如:d="M399 1L799 399L1 399z"
      
l         按键
在FF中,按键事件必须添加在根元素下,而ASV可以添加在任意元素下。
       svgRoot.addEventListener("keypress", tape, false);
而且charCode和keyCode返回的值也有所不同,    ASV中charCode可以得到非字符或数字按键的键值,FF中非字符或数字按键的键值全部返回为0。FF中可以通过keyCode得到这些键值。Opera9.02中不支持charCode,使用keyCode返回所有的键值。因此在使用时可以采用charCode和keyCode相加的办法(null视为0),或者根据浏览器类型决定使用哪个值。FF或Opera9.02中默认的按键快捷方式也可能影响程序的运行,这时必须使用evt.preventDefault()阻止按键消息到达浏览器。
 
按键
带有 ASV 插件的 IE6.0
FireFox1.5
Opera9.02
 
charCode
keyCode
charCode
keyCode
charCode
keyCode
1
49
0
49
0
null
49
SPACE
32
0
32
0
null
32
BACKSPACE
8
0
0
8
null
8
 
l         图形
       ASV缺省对图形(image)进行缩放以适应显示矩形,而FF要指定preserveAspectRatio="none"
 
7,总结,相比ASV,FF比较严格,不能在代码上偷懒,该写的属性,分隔符必须要写全,结构也必须正确。因此在ASV下可以运行的代码如果不专门留意,几乎全部不能在FF下正确显示。而在FF中能够显示的代码,则大部分可以在ASV中显示,二者的显示效果基本相同,但也有部分区别。比较而言,ASV的速度比较快一些,但可惜的是,2009年1月就是ASV寿终正寝的大限了,只能希望FF,OPERA能够对SVG的支持越来越好,IE能早日内置支持SVG,而且不要离W3C标准太远。WEB开发确实需要一个标准的图形语言了,不管是VML,还是SVG。一个统一,开放的标准,和基本遵循标准的实现,才是软件开发人员的福音。
 
SVG通用模板如下:
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:ev="http://www.w3.org/2001/xml-events"
     width="100%" height="100%" onload="init(evt)">
 
       <title>Test</title>
       <desc>SVG test</desc>
       <script type="text/javascript"><![CDATA[
      
       var svgns = "http://www.w3.org/2000/svg";
       var xlinkNS = "http://www.w3.org/1999/xlink";
      
       //Document and root
       var svgDocument = null;
    var svgRoot = null;
 
       function init(evt)
       {
              svgDocument = evt.target.ownerDocument;
          svgRoot = svgDocument.documentElement;
       }
 
       function onEvent(evt)
       {
              var target= evt.target;
              var type = evt.type;
              var code = evt.charCode;
       }
 
        ]]></script>
   
       <defs>
    </defs>
 
       <rect id="background" x="0" y="0" width="100%" height="100%" fill="white" pointer-events="all" />
       <g id="canvas">
       </g>
</svg>
 
 
参考资料:
adobe SVGVIEWER CurrentSupport.pdf
http://www.mozilla.org/projects/svg/status.html
http://www.opera.com/docs/specs/opera9/svg/
http://www.carto.net/papers/svg/eventhandling/
 

你可能感兴趣的:(xml,浏览器,Opera,null,XMLhttpREquest,firefox)