将以Adobe SVG Viewer提供的属性和方法为准,因为不同解析器对JavaScript以及相关的属性和方法支持的程度不同,有些方法和属性是某个解析器所特有的。SVG支持DOM2标准。

12.2.1  文档初始化相关

  evt属性

  evt表示事件本身,可以通过evt获取与当前事件相关的信息,用户可以在script中定义响应函数,进行相应的处理。它与普通JavaScript脚本中的event基本相同,只不过在普通JavaScript的脚本中简写成“e”。

  ownerDocument属性

  通过引用该属性获得当前SVG文件的文档对象,也就是得到SVG的DOM结构。

  使用举例:svgdoc = evt.target.ownerDocument

  getOwnerDocument()方法

  通过调用该方法获得当前SVG文件的文档对象,也就是得到SVG的DOM结构。

  使用举例:svgdoc = evt.target.getOwnerDocument()

  target属性

  通过引用该属性获得事件产生于哪个SVG元素,有时可能是该元素的父元素。

  使用举例:object = evt.target

  getTarget()方法

  通过调用该方法获得事件产生于哪个SVG元素,有时可能是该元素的父元素。

  使用举例:object = evt.getTarget()

  例程12-1  获得SVG文档对象

function init(evt)
{
svgDoc = evt.target.ownerDocument; ②
svgRoot = svgDoc.rootElement;
alert(svgRoot.nodeName);
}
]]>
    
         style="fill:rgb(255,0,0);stroke-width:2"/>

  该例展示了如何在SVG文档被载入后,调用初始化程序,以获得SVG的DOM结构,为后续的编程做好准备。

  例程12-1中,①处表示在SVG文档载入时激活的“onload”事件中执行“init”函数;“init”函数先是得到SVG Document对象,然后获得该对象的根元素(也就是“SVG”元素),最后的效果是弹出一个消息框,上面显示“SVG”。

  ②处的代码可以替换为“svgDoc = evt.getTarget().getOwnerDocument;”,得到的效果是一样的。

12.2.2  DOM对象操作相关

  前面我们已经介绍过,DOM对象是一个树型的结构,并且经过载入后就放在内存中供我们读写。如何对这棵树进行操作,也就成为发挥SVG交互性很关键的一步。下面所示的方法中,有些是文档对象(Document)的方法,有些是文档元素(Element)的方法,需要区别开来。DOM可以分为三大部分:文档基本元素、文档对象和各种类型的从文档基本元素派生出的文档元素。文档对象是文档对象模型的顶级对象,它包含了整个文档的内容。各种类型的文档元素派生自文档基本元素类型,用于描述文档中各种实际存在的元素。其中可以定义一种文档元素,它们可以容纳其他的文档元素,这些元素就是容器元素,实际上文档对象就是最大的容器元素。由于文档对象模型中存在容器元素,因此所有的对象都组成一个树状结构,称为文档对象树或者DOM树,其中根节点就是文档对象。
{reg}
  getElementById(ID_Name)方法

  通过元素的ID名获得该元素。

  使用举例:object = svgdoc.getElementById("map")

  getElementsByTagName(Tag_Name)方法

  通过元素名获得一个或者一组元素,注意方法名中的“Elements”是复数,说明返回的元素可能有多个,是一个“NodeList”。

  使用举例:object = svgdoc.getElementsByTagName ("rect")

  例程12-2  获得SVG文档中的元素

function init(evt)
{
        svgDoc = evt.target.ownerDocument;
        svgRoot = svgDoc.rootElement;
        rect    = svgRoot.getElementById("rect1"); ①
        rects   = svgRoot.getElementsByTagName("rect"); ②
        alert(rect+","+rects);
}

]]>
    
         style="fill:rgb(255,0,0)"/>
    
         style="fill:rgb(255,0,0)"/>
    
         style="fill:rgb(255,0,0)"/>

  打开该文档后,弹出的消息框上显示“[object SVGRectElement],[object NodeList]”。

  例程12-2中,①处使用“rect1”的ID名得到了“svgRoot”下属的一个矩形元素(SVGRectElement)。②是为了获得所有“svgRoot”下属的“”元素,返回的是一个“NodeList”,本例中一共有三个符合条件的元素。

  getAttribute(ID_Name)方法

  根据所提供的ID名来获得元素的属性值。

  使用举例:color = node.getAttribute ("fill")

  setAttribute(Attribute_Name,Value)方法

  设置该元素属性名为“Attribute_Name”的,属性的值为“Value”。

  使用举例:color = node.getAttribute ("fill")

  setAttributeNS(NameSpace, Attribute_Name ,Value)方法

  功能效果同 setAttribute方法,区别就是增加了为属性名加上命名空间(NameSpace)。在ASV3.0中,属性名都是默认SVG的命名空间,所以不需要再特别注明,但是如果你要使用“xlink”中的属性,就要加入相应的命名空间“http://www.w3.org/2000 /xlink/namespace/”。

  使用举例:object = svgdoc.setAttributeNS ("http://www.w3.org/2000/xlink/namespace/", xlink:href, "index.html")

  注意:绝对不要在同一个程序中混合使用DOM1非名称空间API和DOM2名称空间感知的API(例如,createElement和 createElementNS)。如果使用名称空间,请尽量在根元素位置声明所有名称空间,并且不要覆盖名称空间前缀,否则情况会非常混乱。一般来说,只要按照惯例,就不会触发使你陷入麻烦的临界情况。

例程12-3  设置SVG元素的属性

function init(evt)
{
svgDoc = evt.target.ownerDocument;
svgRoot = svgDoc.rootElement;
rect1   = svgRoot.getElementById("rect1");
rect2   = svgRoot.getElementById("rect2");
}
function setSvgAttribute(evt,flag)
{
if ( flag == 1)
rect1.setAttribute("fill", "green"); ①
else
{
rect2.setAttributeNS(null, "fill", "green");  ②
}
}
function getSvgAttribute(evt)
{
alert(rect1.getAttribute("fill")+ "," + rect1.getAttribute("height")); ③
}
]]>
    
        onclick="getSvgAttribute(evt)" onmousemove="setSvgAttribute(evt,1) "
         style="fill:rgb(255,0,0)"/>
    
        onclick="setSvgAttribute(evt,2)"
         style="fill:rgb(255,0,0)"/>

  这里例子中我们接触到了SVG中的事件,这跟HTML中的事件很相似,关于SVG的事件我们会在后面的章节中做详细介绍。这里用到了两个事件:一个是鼠标单击事件“onclick”,一个是鼠标移动到“”时触发的“onmousemove”事件,,注意它们的大小写,全部是小写,否则事件无法激活,浏览器会报告脚本错误。

  我们想要实现的效果是,单击ID为“rect1”的矩形时,能得到它的填充颜色值和矩形的高度值,并且鼠标移动到该矩形的时候,矩形的填充颜色从红色变成绿色;另外一个矩形,我们在单击它的时候,它的填充颜色从红色变成绿色。

  例程12-3中,①处设置矩形“rect1”的“fill”属性为“green”;。

  ②通过命名空间来设置属性值。不过命名空间参数的值是“null”,因为ASV3.0已经内置了命名空间,所以你再给这些SVG的属性添加命名空间的话就会出错,所以填入“null”值。

  ③是为了弹出消息框,显示我们需要知道的那两个属性值。

  createElement(Element_Type)方法

  在DOM对象内创建一个新的元素,可以指定创建哪一种类型的元素,并且返回对这个新元素的引用。

  使用举例:newnode = svgdoc.createElement("rect")

  appendChild(Element)方法

  在该元素的最后追加一个孩子节点。

  使用举例:someElement.appendChild(node)

  例程12-4  动态创建SVG的元素

function alertMsg(evt)
{
objet=evt.target;
large=objet.getAttribute("width");
alert("Width of the rectangle is:" + evt.target.getAttribute ("width"));
}
function init(evt)
{
svgdoc=evt.target.ownerDocument;
node=svgdoc.createElement("rect"); ①
node.setAttribute("x","50");
node.setAttribute("y","50");
node.setAttribute("width","100");
node.setAttribute("height","50");
node.setAttribute("style","fill:red");
node.addEventListener("mousemove",alertMsg,false); ②
group=svgdoc.getElementById("group");
group.appendChild(node); ③
}
]]>
    
        Click the rectangle

  在上面这个SVG文档中,没有看到对“rect”元素的定义,但是实际显示的时候还是显示了一个红色的矩形,原因就在于例程12-4中①处,我们使用“createElement”方法动态生成了一个矩形元素,并且逐个设置了它的“x”、“y”、“width”、“height”及“fill”属性,并且在②处为该元素添加了“mousemove”事件及事件相应的函数名。但是这样生成的矩形元素依旧还是“流离失所”,无法显示出来,需要使用appendChild、insertBefore、 replaceChild等方法把生成的节点元素添加到其它其他元素下才能显示。所以,执行③处的语句后,生成的新元素被加入到名为“group”的组中去,从而显示出来。最终的DOM结构为:如图12-1所示。

***图1

图12-1  动态生成SVG元素后的DOM结构

  从图12-1中可以看出,新加入的“rect”元素与之前就存在的“text”元素位置并列。

  replaceChild(newElement, oldElement)方法

  在某元素的子节点中,使用新元素替代旧元素。

  使用举例:someElement.replaceChild(newNode, oldNode)

  例程12-5  replaceChild方法使用举例

function init(evt)
{
svgdoc = evt.target.ownerDocument;
root = svgdoc.rootElement;
}
function change(evt)
{
obj = evt.target; ①
node=svgdoc.createElement("rect");
node.setAttribute("x",150);
node.setAttribute("y",150);
node.setAttribute("width","100");
node.setAttribute("height","50");
node.setAttribute("style","fill:blue");
root.replaceChild(node,obj); ②
}
]]>
     ③

  这个例子想要实现的效果是:单击一个黑色的矩形后,使它移动到新的位置,并且填充颜色变成蓝色。可以使用动画的办法来实现,但现在我们要用编写动态脚本的方法来实现。例程12-5中,③处已经存在一个黑色矩形了,单击后触发事件执行“change”函数。①的“obj”就是产生事件的“rect”元素,也就是此后要被替代掉的那个元素。然后创建一个新的 “rect”元素,设置新的位置属性和填充颜色值。在②处进行元素的替代,③处的矩形元素就被替换成新的矩形元素,旧的矩形元素不复存在,从而也在显示区域内消失。

  removeChild(Element)方法

  删除某元素下的指定元素。

  使用举例:someElement.replaceChild(Node)

  insertBefore(newElement,refElement)方法

  newElement是一个包含新子元素地址的对象,refElement是参照元素的地址,新子元素被插到参照元素之前。如果refElement参数没有包含在内,或者refElement不是此集合的成员,新的子元素会被插到该元素子元素列表的末尾。

  使用举例:objDocumentElement =someElement.insertBefore(newNode, refNode)

  cloneNode(true/false)方法

  复制一个新的元素,并且返回对这个元素的引用。

  使用举例:someElement.cloneNode(true)

  例程12-6  删除、插入、复制一个新元素

function init(evt)
{
svgdoc = evt.target.ownerDocument;
root = svgdoc.rootElement;
}
function remove(evt) ①
{
obj = evt.target;
root.removeChild(obj);
}
function insert(evt) ②
{
obj = evt.target;
node=svgdoc.createElement("rect");
node.setAttribute("x",150);
node.setAttribute("y",150);
node.setAttribute("width","100");
node.setAttribute("height","50");
node.setAttribute("style","fill:blue");
root.insertBefore(node,obj);
}
function clone(evt) ③
{
obj = evt.target;
var newNode = obj.cloneNode(true);
newNode.setAttribute("y", 300);
newNode.setAttribute("style", "fill:blue");
root.appendChild(newNode);
}
]]>

  该例中有三个矩形元素,分别进行删除、插入和复制操作。例程12-6中,函数①进行删除元素的操作,直接调用“removeChild”方法,要删除的是在root 元素下的“rect”元素,执行后,“rect”元素被删除,矩形也就消失了;函数②依旧是先在内存中生成一个新的“rect”元素,然后使用 “insertBefore”方法把它插入到产生事件的那个“rect”元素的前面,两者是并列的位置;函数③先是“克隆”了一个与产生事件的 “rect”元素一模一样的元素,并且返回给局部变量“newNode”,我们再对这个局部变量设置了属性“y”和填充颜色,然后把这个元素追加到 “root”元素内的最后的位置,使它显示出来。

  firstChild属性、getFirstChlid()方法

  获得某个元素的第一个子元素。

  使用举例:node = someElement.firstChild

  或node = someElement.getFirstChild()

  childNodes属性、getChildNodes()方法

  获得某个元素下面所有的子元素。

  使用举例:nodeList = someElement.childNodes

  或nodeList = someElement.getChildNodes()

  item(n)方法

  当获得了一个元素集合的时候,需要使用该方法进行引用。

  使用举例:node = someElement.childNodes.items(1)

  NodeType属性

  节点类型,是一个枚举量。

  使用举例:i = someElement.NodeType

  详见下面的列表12-1:

  表12-1  节点类型

  返回的整数 节点类型常数 
 1  ELEMENT_NODE
 2  ATTRIBUTE_NODE
 3  TEXT_NODE
 4  CDATA_SECTION_NODE
 5  ENTITY_REFERENCE_NODE
 6  ENTITY_NODE
 7  PROCESSING_INSTRUCTION_NODE
 8  COMMENT_NODE
 9  DOCUMENT_NODE
 10  DOCUMENT_TYPE_NODE
 11  DOCUMENT_FRAGMENT_NODE
 12  NOTATION_NODE

  NodeName属性

  节点名。

  使用举例:name = someElement.NodeName

  详见表12-2。

  表12-2  节点名称

 返回的字符串  说    明
 #comment  这是一个注释节点
 #document  这是一个文档节点
 Element.tagName  元素的标记名,同时也说明这是一个元素
 Attri.name  属性的名字,同时也说明这是一个元素
 #text  这是一个文本节点

  例程12-7  SVG节点操作

function init(evt)
{
svgdoc = evt.target.ownerDocument;
root = svgdoc.rootElement;
alert("First node of root:" + root.firstChild.nodeName); ①
alert("Seconde child node of root:"+root.getChildNodes().item(1). nodeName); ②
var obj = svgdoc.getElementById("words");
alert("Third child node of text element:"+obj.childNodes.item(0). nodeName); ③
}
]]>
    
        
             style="fill:rgb(255,255,255);stroke:rgb(0,0,0);stroke-width:2"/>
        
W
             orld!

  这个例子帮助大家更加深刻地理解SVG的DOM树型结构。

  例程12-7中,①是为了取到“svg”元素下的第一个子元素,也就是“script”元素,所以执行后消息框显示“First node of root:script”;。

  ②是使用“getChildNodes”方法取到“svg”下所有子元素,然后再引用第2个元素(索引值同数组相同,从0开始),执行后消息框显示 “First node of root:g”,也可以使用“root.firstChild. nextSibling.nodeName”语句获得同样的效果,这里的“nextSibling”属性指的是紧挨着某个元素的下一个元素;。

  ③是取得“text”元素下的所有子元素,然后取得这些子元素的第一个元素也就是“tspan”元素,执行后显示“Third child node of text element:tspan”。在使用这些取节点元素的方法或者属性时,一定要小心地数好元素的排列顺序,稍有不慎就会引起错误,所以应该尽可能减少引用层次。

  attributes

  获得某元素的属性集合。

  使用举例:attributes = someElement.attributes

  length属性、getLength()方法

  获得集合元素所含有元素的个数,如attributes、childNodes属性有此属性或方法。

  使用举例:len = attributes.length

  或len = attributes.getLength()

  例程12-8  SVG遍历元素值操作

function information(evt)
{
obj=evt.target;
att=obj.attributes; ①
str="Attributs:\nNumber: "+att.length;
for (i=0; i
{
str = str+"\n"+att.item(i).name+" : "+att.item(i).value;
}
alert(str);
}
]]>
    
         style="fill:rgb(0,0,255);opacity:0.7" onclick="information(evt)"/>

  这个例子很好理解,就是遍历矩形元素的所有属性值,在①处,通过attributes获得一个属性值的集合,然后同“childNodes”属性类似,可以使用“item()”方法进行引用,从而获得相应的属性值,如图12-2所示。

  图12-1  2  遍历属性值的显示结果

***2

图2

  12.2.3  事件对象evt相关

  clientX属性、getClientX()方法

  鼠标指针相对于浏览器窗口的客户区的X坐标。

  使用举例:cx = evt.clientX 或 cx = evt.getClientX()

  clientY属性、getClientY()方法

  鼠标指针相对于浏览器窗口的客户区的Y坐标。

  使用举例:cx = evt.clientY 或 cx = evt.getClientY()

  注意:这两个坐标并没有计算文档的滚动高度或者宽度,如果事件发生在窗口的最上边,不管这个文档已经向下滚动了多远,clientX或clientY都是0

  screenX属性、getScreenX()方法

  鼠标指针相对于用户显示器左上角的X坐标。

  使用举例:sx = evt.screenX 或 sx = evt.getScreenX()

  screenY属性、getScreenY()方法

  鼠标指针相对于用户显示器左上角的Y坐标。

  使用举例:sx = evt.screenY 或 sx = evt.getScreenY()

  例程12-9  SVG动态获得和设置样式操作

function mousePos(evt)
{
cx=evt.clientX;cy=evt.clientY;
sx=evt.getScreenX();sy=evt.getScreenY();
root=evt.target.ownerDocument;
root.getElementById("pos1").firstChild.setData("Client: "+cx+" "+cy);
root.getElementById("pos2").firstChild.setData("Screen: "+sx+" "+sy)
}
]]>

style="stroke-width:1; stroke:black;fill:white"/>

  这个例子不复杂,就是获得鼠标当前的客户区坐标和屏幕坐标,这两个坐标其实有着“相对坐标”和“绝对坐标”的味道。但是很奇怪的是,在这个例子中,不论鼠标在什么地方,浏览器窗口在什么地方,两个坐标值总是相等的。

  getCharCode()方法

  获得键盘输入的字符的ASCII码。

  使用举例:key = evt.getCharCode()

  例程12-10  SVG动态获得键盘输入字符

var phrase="";
        function type(evt)
        {
            svgdoc=evt.target.ownerDocument;
            key=evt.getCharCode(); ①
            if (key==8)
            {
                if (phrase!="")
                {
                    phrase=phrase.substring(0,phrase.length-1);
                }
            }
            else
            {
                letter=String.fromCharCode(key); ②
                phrase=phrase+letter;
            }
            obj = svgdoc.getElementById("enter");
            child = obj.firstChild.setData(phrase);
        }
    ]]>
    
        
             style="fill:rgb(255,255,255)"/>
         Display here

  例程12-10很有趣,用来实时地显示用户在键盘上输入的字符。首先使用①处的“getCharCode”方法获得字符的ASCII码,如果是控制键(如Ctrl、Alt、方向键等),则该方法自动过滤掉这些字符。②处的“String.fromCharCode”方法可以把获得的ASCII码转换成相应的字符。

12.2.4  字符串及文本相关

  createTextNode(TextContent)方法

  动态生成文本节点的文本内容。

  使用举例:text = svgdoc.createTextNode("SVG")

  例程12-11  SVG动态生成节点

function creatTextNode(evt)
    {
        svgtarget = evt.getTarget();
        svgdoc = svgtarget.ownerDocument;
        node   = svgdoc.createElement("text"); ①
        node.setAttribute("x","50");
        node.setAttribute("y","50");
        node.setAttribute("style","text-anchor:middle;font-size:25; font-family:Arial;fill:red");
        text = svgdoc.createTextNode("SVG"); ②
        node.appendChild(text);
        ou = evt.getTarget();
        svgtarget.appendChild(node);
    }
    ]]>

  例程12-11向我们展示了如何动态地生成一个文本节点,并添加这个节点文本内容。首先需要生成一个“text”元素,①处开始的代码就做了这样一件事情,相信大家已经很熟悉这种动态生成元素的方法了,这里不再赘述。②处的代码调用了“createTextNode”方法,参数就是“text”元素的文本内容,也就是要显示出来的内容。然后使用 “appendChild”方法添加到新创建的“text”元素中去。最后再把整个新创建好的元素加入到根元素中。例子中没有任何实现定义好的 “text”元素,完全通过脚本程序动态生成。

  getNumberOfChars()方法

  获得元素所包含的文本字符的个数(包括空格)。

  使用举例:number = someElement.getNumberOfChars()

  getComputedTextLength()方法

  获得元素所包含的文本字符的显示长度。

  使用举例:len = someElement.getComputedTextLength()

  selectSubString(i,j) 方法

  高亮显示元素所包含的文本字符串中第i个字符(不包括i)后的j个字符。

  使用举例:letter = someElement.selectSubString (2,3)

  例程12-12  元素文本字符相关方法

function detail(evt)
{
textdoc=evt.target.ownerDocument;
textNode=textdoc.getElementById("mtext");
number = textNode.getNumberOfChars(); ①
len = textNode.getComputedTextLength(); ②
textNode.selectSubString(2,3); ③
alert("Total:" + number + "\n"+"Length:" + len);
}
]]>
    
         style="text-anchor:middle;font-size:24;font-family:Arial;fill:rgb(255,0,0)"> Welcome to SVG world!

  上述三个方法是针对“text”元素的,只有“text”元素才能使用。

  例程12-12中,①处代码计算了该文本元素所含的文本字符的数字,此例是计算“Welcome to SVG world!”这个字符串的字符个数,一共有21个;

  ②处代码计算字符串的显示长度,单位是像素;

  ③处代码执行后,“lco”这几个字母呈现蓝色背景高亮显示,即第2个字母“l”后3个字母高亮显示。

12.2.5  样式相关

  style属性、getStyle()方法

  获得某元素的样式值,单独使用没有太大的意义,需要配后合后续两个方法一起使用。

  使用举例:style = someElement.style 或style = someElement.getStyle()

  setProperty(Style_Name, Value)方法

  设置某元素的某样式项的值。

  使用举例:someElement.style.setProperty("fill","red")

  或someElement.getStyle().setProperty("fill","red")

  getProperty(Style_Name)方法

  获得某元素的某样式项的值。

  使用举例:someElement.style.getProperty("fill")

  或someElement.getStyle().getProperty("fill")

  例程12-13  SVG动态获得和设置样式操作

function information(evt)
{
obj  =  evt.target;
style = obj.getStyle(); ①
alert(style.getPropertyValue("fill")); ②
}
function changeStyle(evt)
{
obj  =  evt.target;
obj.style.setProperty("fill","red"); ③
obj.style.setProperty("opacity",1);
}
]]>
    
         style="fill:rgb(0,0,255);opacity:0.7" onclick="information(evt)"/>
    
         style="fill:rgb(0,0,255);opacity:0.7" onclick="changeStyle(evt)"/>

  例12-13中有两个矩形,单击上方的那个矩形,会弹出一个消息框显示该矩形的填充颜色值“blue”;单击另外一个矩形,矩形的填充颜色和透明度分别变成红色和不透明。在①处获得了产生事件的这个矩形的样式信息,通过②处的“getPropertyValue”方法可以获得样式信息中你想要的某项的值,这里我们获取了“fill”属性的值。我们要对另外一个矩形产生改变样式的效果,就需要使用③处的“setProperty”方法,传入的参数是样式项目名称和要修改的目标值。无论是获得还是设置样式值的方法,都必须跟在“style”属性或“getStyle”方法的后面才有效。

12.2.6  图形变换相关

  getBBox()方法

  返回一个SVGRect矩形对象,这个矩形表示该SVG元素的外包矩形。

  使用举例:someElement.getBBox()

  例程12-14  在可视区域内移动一段文字

var isMove=false,cible="",xt1=0,yt1=0;
    function init(evt)
    {
        svgdoc=evt.target.ownerDocument;
        obj=svgdoc.getElementById("mtext");
        contour=obj.getBBox(); ①
        trace="M"+contour.x+" "+contour.y+" l"+contour.width+" 0 0 "+contour.height+" -"+contour.width+" 0z"; ②
        obj=svgdoc.getElementById("rectBox");
        obj.setAttribute("d",trace);
    }
    function mouseMove(evt)
    {
    xm=evt.clientX;ym=evt.clientY;
    if ((cible=="rectBox")&&(isMove==true))
    {
            obj=svgdoc.getElementById("mtext"); ③
            var
xt2=parseInt(obj.getAttribute("x")),yt2=parseInt(obj. getAttribute("y"));
            var depx=xt2+xm-xt1,depy=yt2+ym-yt1;
            obj.setAttribute("x",depx);
            obj.setAttribute("y",depy);
            contour=obj.getBBox();
            target=svgdoc.getElementById(cible);
            trace="M"+contour.x+" "+contour.y+" l"+contour.width+" 0 0 "+contour.height+" -"+contour.width+" 0z";
            target.setAttribute("d",trace);
            xt1=xm;yt1=ym;
        }
    }
    function cancel(evt) ④
    {
        isMove=false;
    }
    function moveDown(evt) ⑤
    {
        cible=evt.getTarget().getAttribute("id");
        if (cible=="rectBox")
    {
        isMove=true;
        xt1=parseInt(evt.clientX);
        yt1=parseInt(evt.clientY);
    }
}
]]>
    
        
             style="fill:rgb(255,255,255)"/>
        
            SVG

  例程12-14比较复杂,希望大家耐心一些。例子想要实现的效果是拖动“SVG”这段文字,在一个矩形区域内移动,充分体现了SVG的交互性。

  图形部分主要是一个“text”元素和“path”元素,“path”元素帮助绘制一个背景矩形区域,使得用户在操作时无需无须非常小心地单击到文字才能触发事件,只要鼠标在这个矩形区域内进行操作即可,可以称之为“热区”。为了让大家能够清楚地看到这个区域又不影响使用,设置透明度为不完全透明。例子中的事件主要有三个:鼠标键按下时(onmousedown)、鼠标键弹起时(onmouseup)和鼠标移动时(onmousemove),注意它们被放在了不同的地方,被激活的范围有所不同。

  初始化程序初始化了上述的“热区”,也就是包裹着“SVG”这三个文字的最小矩形,使用“getBBox”方法获得这个外包矩形框,然后使用路径绘制这个封闭区域。

  当鼠标键按下时,⑤处的代码被执行。首先判断“cible”变量是不是“rectBox”,也就是判断事件的来源是不是在“SVG”这几个字的矩形区域内产生的,如果在这个区域外产生,则后续的效果都不会产生,也就无法拖动文字移动了。“isMove”这个变量就是用来控制是否能够移动文字。此外,还记住了当前鼠标的位置。

  如果 “isMove”变量是“true”的话,当鼠标移动时,③处以下的代码都会被执行。要使文字能够移动,就要改变它们相对位置偏移属性“x”和“y”。一旦文字的位置改变了,它的外包矩形区域也就改变了,我们要使用“getBBox”方法获得这个外包矩形框,并且重绘一遍。所以,最后的效果就是这个外包矩形框和文字一起移动了。

  鼠标键弹起时,执行④处的代码,“isMove”变量又被置回“false”,本次操作完成。

  getCTM()方法

  返回一个初始变换矩阵。

  使用举例:someElement.getBBox()

  currentScale属性、getCurrentScale()方法

  获得当前视图的缩放比例。

  使用举例:someElement.currentScale

  或someElement.getCurrentScale()

  currentTranslate()属性、getCurrentTranslate()方法

  获得当前视图的平移距离的SVGPoint对象。

  使用举例:someElement.currentTranslate

  或someElement.getCurrentTranslate()

  例程12-15  SVG动态获得当前坐标系统信息

function info(evt)
    {
        xm=evt.clientX;ym=evt.clientY;
        svgdoc=evt.target.ownerDocument;
        root=svgdoc.getElementById("root");
        scale=root.currentScale;
        tx=root.currentTranslate.x;
        ty=root.currentTranslate.y;
        xsvg=-200+(xm-tx)*5/scale;
        ysvg=-200+(ym-ty)*5/scale;
        svgdoc.getElementById("pos1").firstChild.setData("ClientX clientY: "+xm+" "+ym);
        svgdoc.getElementById("pos2").firstChild.setData("ViewBox: "+xsvg+" "+ysvg);
        svgdoc.getElementById("pos3").firstChild.setData("current Translate: "+tx+" "+ty);
        svgdoc.getElementById("pos4").firstChild.setData("currentScale: "+scale);
    }
    ]]>

style="stroke-width: 1;stroke:black;fill:#999999" />

ViewBox: 
ViewBox: -200 -200 1750 1750
Centre 700 180

CurrentTranslate: 
CurrentScale :

  这几个函数很有用,通过它们可以获得当前SVG视图的平移以及变形情况,这样视图内的其它其他元素就有了参照值。

12.2.7  XML序列化相关

  printNode(Element)方法

  将参数Element节点解析为字符串。

  使用举例:printNode(node)

  parseXML(string)方法

  将参数字符串序列化成一个节点对象。

  使用举例:parseXML(string , svgdoc)

  例程12-16  XML和DOM对象之间的序列化和逆序列化

function init(evt)
{
svgdoc = evt.target.ownerDocument;
}
function node2string(evt)
{
node = evt.target;
string = printNode(node); ①
alert(string);
}
function string2node()
{
string = "
              stroke='#000000' />";
node = parseXML(string, svgdoc);  ②
svgdoc.rootElement.appendChild(node);
}
]]>
    
         style="stroke-width:1;stroke:rgb(0,0,0);fill:rgb(0,0,0)"
        onclick="node2string(evt)"/>
    
         style="stroke-width:1;stroke:rgb(255,0,0);fill:rgb(255,0,0)"
        onclick="string2node()"/>

图12--23是单击了黑色矩形后的显示结果。图12-4是单击了红色矩形后的显示结果,在左上角出现了一个小圆。

***

图12-3  printNode方法执行结果

***

图12-4  parseXML方法执行结果

  这两个方法刚好是相互对应的一组函数,这一组函数用于进行字符串和DOM节点之间的转换。我们可以使用printNode()逆序列化指定节点元素,用于将当前SVG文档中的Node元素生成字符串保存为文本文件或提交给远程服务器。相反地,我们也可以通过parseXML()将一个字符串用指定的文档对象解析为一个节点(Node)对象;在Adobo SVG Viewer环境下可以不指定document对象,系统会默认使用当前SVG文档的Document对象解析字符串,所以在②处的“svgdoc”可以替换成“document”关键字。

  例程12-16中,①处代码就是把这个节点转换成一个字符串,字符串内容就是这个节点的内容,如图12--23所示。

  ②处的代码把事先定义后的字符串内容(字符串内容是合法的符合SVG语法的语句)通过解析后成为一个DOM对象的节点,并且添加到DOM对象中,使之能够显示出来

SVG DOM常用属性和方法介绍的更多相关文章

  1. SVG DOM常用属性和方法介绍(1)

    12.2  SVG DOM常用属性和方法介绍 将以Adobe SVG Viewer提供的属性和方法为准,因为不同解析器对JavaScript以及相关的属性和方法支持的程度不同,有些方法和属性是某个解析 ...

  2. Html DOM 常用属性和方法

    Node对象的节点类型***************************************************接口 nodeType常量 nodeType值 备注Element Node ...

  3. jqGrid常用属性和方法介绍

    jqGrid API中文手册:http://blog.mn886.net/jqGrid/ 一.jqGrid属性: width:Grid的宽度,如果未设置,则宽度应为所有列宽的之和:如果设置了宽度,则每 ...

  4. HTML DOM对象的属性和方法介绍(原生JS方法)

    HTML DOM对象的属性和方法介绍 DOM 是 Document Object Model(文档对象模型)的缩写. DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口), ...

  5. C# 常用控件属性及方法介绍

      C#常用控件属性及方法介绍                                               目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox ...

  6. 【转载】C#常用控件属性及方法介绍

    C#常用控件属性及方法介绍                                               目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文 ...

  7. UploadifyAPI-上传插件属性和方法介绍

    上一篇文章简单的介绍了Uploadify上传插件的使用.但是对于常用的属性和方法并没有说明.授人以鱼不如授人以渔,我决定将常用的属性列举出来,供大伙参考参考.           Uploadify属 ...

  8. Node.js process 模块常用属性和方法

    Node.js是常用的Javascript运行环境,本文和大家发分享的主要是Node.js中process 模块的常用属性和方法,希望通过本文的分享,对大家学习Node.js http://www.m ...

  9. ios基础篇(四)——UILabel的常用属性及方法

    UILabel的常用属性及方法:1.text //设置和读取文本内容,默认为nil label.text = @”文本信息”; //设置内容 NSLog(@”%@”, label.text); //读 ...

随机推荐

  1. string类find函数返回值判定

     string类find函数返回值判定 代码示例 #include<iostream> #include<cstring> using namespace std; int m ...

  2. js 获得日期相差天数

    function getDays(strDateStart,strDateEnd){               var strSeparator = "-"; //日期分隔符   ...

  3. selenium杀掉浏览器进程方法

    * 杀掉浏览器进程      */     public static void operateWindowsProcess(){         WindowsUtils.tryToKillByNa ...

  4. Giving Data Backup Option in Oracle Forms 6i

    Suppose you want to give the data backup option in Oracle Forms application to some client users, wh ...

  5. Arduino学习笔记二:修改LED点灯程序

    看了开源社区的LED控制程序,开始上手代码编写,修改,下载以及调试,原文地址:http://www.arduino.cn/thread-1072-1-1.html,这个帖子写的比较通俗易懂. 自己移植 ...

  6. iOS - Project 项目

    1.项目流程 1.1 分析项目的架构 iOS 常见的几种架构 标签式 Tab Menu 列表式 List Menu 抽屉式 Drawer 瀑布式 Waterfall 跳板式 Springborad 陈 ...

  7. Effective Objective-C 2.0 学习记录

    由于最近入职,公司安排自由学习,于是有时间将Effective Objective-C 2.0一书学习了一遍.由于个人知识面较窄,对于书中有些内容无法理解透彻,现将所学所理解内容做一遍梳理,将个人认为 ...

  8. [SoapUI] Post请求Body里面限制特殊字符(&、%),Groovy脚本里特殊字符需要添加“\”转义($)。

    SoapUI的Post请求,在body里面不能包含(&.%),如果含有这些特殊字符,请求会报错:在添加的Groovy脚本里有些特殊字符需要使用“\”转义($),不然也会报错.

  9. HBase之计数器

    HBase计数器 #创建counters表 列族['daily','weekly','monthly'] hbase(main):001:0> create 'counters','daily' ...

  10. 手机号 和 email 的正则匹配

    手机号   /^1[3|4|5|8] \d{9}$/ email  /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/