SVG有四種常用的滑鼠響應的指令碼寫法(SMIL方式、Attributes方式、JavaScript+SMIL方式、EventListener方式),根據不同的需要讓大家有更多的選擇。本文介紹了四種實現SVG滑鼠事件的例子。
SVG滑鼠事件實現方式的例子效果是:單擊一個紅色的矩形後,它的填充顏色會變成藍色
1 SMIL方式
常式1 滑鼠事件之SMIL方式
<svg><rect x="15" y="15" width="40" height="40" fill="red"><set attributeName="fill" to="blue" begin="click"/></rect></svg>
在前面有關“動畫”效果的章節中我們使用過類似的方法,也就是在單擊後觸發一個動畫效果,此例中被改變的是“fill”屬性,由紅變藍,中間沒有漸層的過程,一次到位。
2 Attributes方式
常式2 滑鼠事件之Attributes方式
<svg xmlns="http://www.w3.org/2000/svg"xmlns:xlink=http://www.w3.org/1999/xlinkxmlns:a3="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"a3:scriptImplementation="Adobe"><script type="text/ecmascript" a3:scriptImplementation="Adobe"><![CDATA[function changeColor(evt){var rect = evt.target;rect.setAttributeNS(null, "fill", "blue")}]]></script><rect x="5" y="5" width="40" height="40"fill="red"onclick= "changeColor(evt)"/> u</svg>
這種事件觸發方式想必大家已經很熟悉了,在上一節中,滿眼儘是這種事件觸發方式,即把事件觸發作為元素的屬性與其它其他屬性寫在一起。事件屬性在u處,“onclick”事件調用的是“changeColor”函數,參數是“evt”,這樣使得函數內部指令碼可以從“evt”獲得事件相關資訊。這種方式比較常用。
3 JavaScript+SMIL方式
常式3 滑鼠事件之JavaScript+SMIL方式
<svg onload="makeShape(evt)"><script><![CDATA[var svgns = "http://www.w3.org/2000/svg";ufunction makeShape(evt) {svgDoc = evt.target.ownerDocument;var rect = svgDoc.createElementNS(svgns, "rect");vrect.setAttributeNS(null, "x", "5");rect.setAttributeNS(null, "y", "5");rect.setAttributeNS(null, "width", "40");rect.setAttributeNS(null, "height", "40");rect.setAttributeNS(null, "fill", "red");var set = svgDoc.createElementNS(svgns, "set");set.setAttributeNS(null, "attributeName", "fill");set.setAttributeNS(null, "to", "blue");set.setAttributeNS(null, "begin", "click");rect.appendChild(set);svgDoc.rootElement.appendChild(rect);}]]></script></svg>
這個例子沒有圖形元素的事先定義,所有定義都是通過指令碼完成的,包括事件的定義也都是動態指令碼完成的,最後在記憶體中的SVG DOM機構與常式1是類似的。常式3中,v處的“createElementNS”方法,有了一個尾碼“NS”是需要添加命名空間參數的,這裡的命名空間定義在u處。
作者註:本方式本人測試在FF(Firefox)下沒成功,報了一個錯誤。
4 EventListener方式
常式4 滑鼠事件之EventListener方式
<svg onload="makeShape(evt)"><script><![CDATA[var svgns = "http://www.w3.org/2000/svg";function makeShape(evt) {if ( window.svgDocument == null )svgDoc = evt.target.ownerDocument;var rect = svgDoc.createElementNS(svgns, "rect");rect.setAttributeNS(null, "x", 15);rect.setAttributeNS(null, "y", 15);rect.setAttributeNS(null, "width", 40);rect.setAttributeNS(null, "height", 40);rect.setAttributeNS(null, "fill", "red");rect.addEventListener("click", changeColor, false); usvgDoc.documentElement.appendChild(rect);}function changeColor(evt) {var target = evt.target;target.setAttributeNS(null, "fill", "blue");}]]></script></svg>
這種方法也是經常用到的,W3C為是DOM元素繫結事件處理函數唯一真正的標準方式。原理就是使用“addEventListener”方法來註冊事件方法,而且一次性可以很方便地註冊很多事件,“EventListener”被稱為“事件監聽器”。 “addEventListener”這個方法的參數依次是:事件的名稱(如:click)、處理該事件的函數名和是否啟用事件捕獲的布爾量(一般是false)。
作者註:本方式本人測試在FF下沒成功,報了一個錯誤。
常式4中,u處調用了“addEventListener”方法來註冊“onclick”事件,事件處理函數是“changeColor”。值得注意的是寫在參數裡的事件名稱,要去掉“on””,所以填寫的是“click”,而不是“onclick”。
在“addEventListener”的方法中有一個參數表示是否啟用事件捕捉,要理解這個變數的作用,我們需要瞭解一下在DOM2事件模型中,事件傳播的三個階段。
首先,在捕獲階段(capturing phase),事件是從文檔對象(Document object)開始,沿著文檔樹向下一直到目標對象傳播.。如果任何目標對象的祖輩(不包括目標對象本身)也有一些指定註冊的捕獲事件的處理常式,在事件傳播的這個階段(捕獲階段)將運行它們,是否啟用事件捕捉的變數的意義也就在於此。
事件傳播的下一個階段發生在目標對象本身:所有註冊到目標對象的對應事件處理常式都被運行。
事件傳播的第三階段是冒泡階段,或者說按文檔層次倒序進行,從目標元素到文檔對象(Document object)。儘管所有的事件都受事件傳播的捕獲階段(capturing phase)的影響,但是並不是所有類型的事件都冒泡,像“mousedown”這樣的一般事件對文檔中的其它其他元素是有意義的,所以這些事件才沿著文檔層次向上冒泡,並且觸發目標元素的祖元素的相應事件的處理常式。通常情況下,原始的輸入事件冒泡,而進階的語義事件不會。