2012-08-29 66 views
1

我有說,在一個HTML頁面的JavaScript的一部分特定的屬性查找SVG元素:與使用JavaScript

function flashElements() { 
    var svg = document.getElementById("mysvg").getSVGDocument(); 
    var all = svg.getElementsByTagName("flash"); 
    for (var i=0, max=all.length; i < max; i++) { 
     if (all[i].flash === "on") 
     { 
      all[i].setAttributeNS(null, "fill", "lime"); 
     } 
    } 
} 

與加載的SVG如下:

<object data="alpha.svg" type="image/svg+xml" id="mysvg" width="800" height="600"></object> 

的想法是調用這在一個特定的觸發器上,如果任何SVG元素具有「flash」的特定屬性,那麼它們的fill屬性將改變顏色。當然,上述不起作用 - 它正在尋找元素,而不是屬性。那麼如何遍歷所有的SVG元素,尋找具有該特定屬性的任何東西?

的SVG有:

<polygon points="203,20 209,32 205,32 203,28" class="trackPlain" flash="on" /> 
<polygon points="205,32 209,32 217,48 213,48" class="trackPlain" flash="off" /> 

其實所有我想要做的是flash元素(開/關),但當然IE不支持動畫。

+1

剛一說明:它是不好的創作實踐中使用非前綴的自定義屬性,你應該使用'定製:閃=「上」'或'數據-flash =「on」'以避免與未來的svg規格衝突。 '自定義'前綴只是一個例子,它可以是任何你定義的(見http://www.w3.org/TR/REC-xml-names/)。 –

+0

好的,我真的好奇!謝謝你的提示。 – GeoffM

回答

2

效率不高,但我想你可以做這樣的事情:

var allElements = svg.getElementsByTagName("*"); 
for(var i = 0; i < allElements.length; i++) { 
    var element = allElements[i]; 

    if(element.getAttribute("myAttr") === "on") { 
     element.setAttribute("fill", "lime"); 
    }  
} 

你的另一個選擇是做一個樹的遍歷。

+0

謝謝,這對我很有用。我嘗試在屏幕上放置10,000個直尺,每750毫秒交替填充一次。在Firefox上,處理器功耗提高了10%在IE 6%上;而且兩者的效果都是同時發生的,而不是我期待的一種擦拭效果。但我不會馬上改變那麼多元素! – GeoffM

+1

如果更有效的變體是var allElements = svg.querySelectorAll(「[data-flash ='on']」);'然後在不比較屬性的情況下循環。 – Duopixel

+0

@Duopixel好點。當我回答並且不認爲使用XPath時,我有點慌張。 –

2

另一個解決方案是使用CSS選擇器,避免改變大量的屬性,效果應該是相同的。

<style> 
    .trackplain[flash="on"] { fill: lime; } 
</style> 

更新:要清楚,上述應放置在SVG文檔內。

+0

對我來說這是一個新的 - 我真的應該正確學習CSS!感謝這個想法。 – GeoffM

0

其他使用答案打字稿& inskscape SVG:

this.mySvg = svg.getElementsByTagName("svg")[0]; 
let myDom = this.svg.getElementsByTagName("*"); 
    for(let i=0; i < myDom.length; i++) { 
     let label = myDom[i].getAttribute('inkscape:label'); 
     let style = myDom[i].getAttribute('style'); 
     if (label && style) { 
      myDom[i].addEventListener("click",() => this.onClick(myDom[i], style)); 
     } 
    }