zoukankan      html  css  js  c++  java
  • SVG DOM常用属性和方法介绍(1)

    12.2  SVG DOM常用属性和方法介绍

    将以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文档对象

    <svg width="640"height="480"onload="init(evt)"> u

    <script><![CDATA[

    function init(evt)

    {

    svgDoc = evt.target.ownerDocument; v

    svgRoot = svgDoc.rootElement;

    alert(svgRoot.nodeName);

    }

    ]]></script>

    <rect x="100"y="100"width="100"height="50"fill="red"stroke-width="2"/>

    </svg>

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

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

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

    12.2.2  DOM对象操作相关

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

    —  getElementById(ID_Name)方法

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

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

    —  getElementsByTagName(Tag_Name)方法

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

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

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

    <svg width="640"height="480"onload="init(evt)">

    <script><![CDATA[

    function init(evt)

    {

            svgDoc = evt.target.ownerDocument;

            svgRoot = svgDoc.rootElement;

            rect    = svgRoot.getElementById("rect1");u

            rects   = svgRoot.getElementsByTagName("rect");v

            alert(rect+","+rects);

    }

    ]]></script>

    <rect id="rect1"x="100"y="100"width="100"height="50"fill="red"/>

    <rect id="rect2"x="100"y="200"width="100"height="50"fill="red"/>

    <rect id="rect3"x="100"y="300"width="100"height="50"fill="red"/>

    </svg>

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

    例程12-2中,u处使用“rect1”的ID名得到了“svgRoot”下属的一个矩形元素(SVGRectElement)。v是为了获得所有“svgRoot”下属的“<rect>”元素,返回的是一个“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元素的属性

    <svg width="640"height="480"onload="init(evt)">

    <script><![CDATA[

    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");u

    else

    {

    rect2.setAttributeNS(null,"fill","green");v

    }

    }

    function getSvgAttribute(evt)

    {

    alert(rect1.getAttribute("fill")+","+ rect1.getAttribute("height"));w

    }

    ]]></script>

    <rect id="rect1"x="100"y="100"width="100"height="50"fill="red"onclick="getSvgAttribute(evt)"onmousemove="setSvgAttribute(evt,1)"/><rect id="rect2"x="100"y="200"width="100"height="50"fill="red"onclick="setSvgAttribute(evt,2)"/>

    </svg>

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

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

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

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

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

    —  createElement(Element_Type)方法

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

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

    —  appendChild(Element)方法

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

    使用举例:someElement.appendChild(node)

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

    <svg width="640"height="480"onload="init(evt)">

    <script><![CDATA[

    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");u

    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); v

    group=svgdoc.getElementById("group");

    group.appendChild(node); w

    }

    ]]></script>

    <g id="group">

    <text x="100"y="20"

    style="text-anchor:middle;font-size:15;fill:red">Click the rectangle </text>

    </g>

    </svg>

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

     
       

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

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

    —  replaceChild(newElement, oldElement)方法

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

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

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

    <svg width="640"height="480"onload="init(evt)">

    <script><![CDATA[

    function init(evt)

    {

    svgdoc = evt.target.ownerDocument;

    root = svgdoc.rootElement;

    }

    function change(evt)

    {

    obj = evt.target; u

    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); v

    }

    ]]></script>

    <rect x="50"y="50"width="100"height="50"onclick="change(evt)"/> w

    </svg>

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

    —  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  删除、插入、复制一个新元素

    <svg width="640"height="480"onload="init(evt)">

    <script><![CDATA[

    function init(evt)

    {

    svgdoc = evt.target.ownerDocument;

    root = svgdoc.rootElement;

    }

    function remove(evt) u

    {

    obj = evt.target;

    root.removeChild(obj);

    }

    function insert(evt) v

    {

    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) w

    {

    obj = evt.target;

    var newNode = obj.cloneNode(true);

    newNode.setAttribute("y", 300);

    newNode.setAttribute("style","fill:blue");

    root.appendChild(newNode);

    }

    ]]></script>

    <rect x="50"y="50"width="100"height="50"onclick="remove(evt)"/>

    <rect x="50"y="150"width="100"height="50"onclick="insert(evt)"/>

    <rect x="50"y="250"width="100"height="50"onclick="clone(evt)"/>

    </svg>

    该例中有三个矩形元素,分别进行删除、插入和复制操作。例程12-6中,函数u进行删除元素的操作,直接调用“removeChild”方法,要删除的是在root元素下的“rect”元素,执行后,“rect”元素被删除,矩形也就消失了;函数v依旧是先在内存中生成一个新的“rect”元素,然后使用“insertBefore”方法把它插入到产生事件的那个“rect”元素的前面,两者是并列的位置;函数w先是“克隆”了一个与产生事件的“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节点操作

    <svg width="640"height="480"onload="init(evt)">

    <script><![CDATA[

    function init(evt)

    {

    svgdoc = evt.target.ownerDocument;

    root = svgdoc.rootElement;

    alert("First node of root:"+ root.firstChild.nodeName); u

    alert("Seconde child node of root:"+root.getChildNodes().item(1). nodeName); v

    var obj = svgdoc.getElementById("words");

    alert("Third child node of text element:"+obj.childNodes.item(0). nodeName); w

    }

    ]]>

    </script>

    <g>

    <rect x="50"y="50"width="100"height="50"

    fill="white"stroke="black"stroke-width="2"/>

    <text id="words"x="100"y="100"style="font-size:20">

    <tspan style="font-size:30">W</tspan>

    <tspan x="110"y="80"> orld!</tspan>

    </text>

    </g>

    </svg>

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

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

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

    w 是取得“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遍历元素值操作

    <svg width="640"height="480">

    <script><![CDATA[

    function information(evt)

    {

    obj=evt.target;

    att=obj.attributes; u

    str="Attributs:nNumber:"+att.length;

    for (i=0; i<att.length; i++)

    {

    str = str+"n"+att.item(i).name+":"+att.item(i).value;

    }

    alert(str);

    }

    ]]></script>

    <rect x="100"y="100"width="150"height="100"style="fill:blue; opacity:0.7"onclick="information(evt)"/>

    </svg>

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

     

    图12-1 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动态获得和设置样式操作

    <svg width="400"height="400"onmousemove="mousePos(evt)">

    <script><![CDATA[

    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)

    }

    ]]></script>

    <rect x="0"y="0"width="400"height="400"  

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

    <text id="pos1"x="5"y="20"style="font-size:15"></text>

    <text id="pos2"x="5"y="40"style="font-size:15"></text>

    </svg>

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

    —  getCharCode()方法

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

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

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

    <svg width="500"height="500">

        <script><![CDATA[

            var phrase="";

            function type(evt)

            {

                svgdoc=evt.target.ownerDocument;

                key=evt.getCharCode();u

                if (key==8)

                {

                    if (phrase!="")

                    {

                        phrase=phrase.substring(0,phrase.length-1);

                    }

                }

                else

                {

                    letter=String.fromCharCode(key); v

                    phrase=phrase+letter;

                }

                obj = svgdoc.getElementById("enter");

                child = obj.firstChild.setData(phrase);

            }

        ]]></script>

        <g onkeypress="type(evt)">

        <rect x="0"y="0"width="400"height="400"style="fill:white"/>

          <text id="enter"x="150"y="50"

    style="text-anchor:middle;font-size: 25; font-family:Arial;fill:red"> Display here</text>

    </g>

    </svg>

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

    12.2.4  字符串及文本相关

    —  createTextNode(TextContent)方法

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

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

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

    <svg width="400"height="400"onload="creatTextNode(evt)">

        <script><![CDATA[

        function creatTextNode(evt)

        {

            svgtarget = evt.getTarget();

            svgdoc = svgtarget.ownerDocument;

            node   = svgdoc.createElement("text");u

            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");v

            node.appendChild(text);

            ou = evt.getTarget();

            svgtarget.appendChild(node);

        }

        ]]></script>

     

     

    程序员的基础教程:菜鸟程序员

  • 相关阅读:
    for else
    改变注释字体颜色
    多继承
    模块的查找顺序
    如何跳出多层嵌套
    验证码书写
    正则表达式(一)
    四、列表与超链接
    三、表格与表单
    二、HTML入门
  • 原文地址:https://www.cnblogs.com/guohu/p/5086084.html
Copyright © 2011-2022 走看看