对于use元素当引用的symbol当只有填充色或线色变化时可以通过给use元素添加class来减少代码量。直接上代码
<!DOCTYPE html>首先看初始加载效果图
<html>
<head>
<style type="text/css">
svg line {
stroke: inherit;
}
use.uncharged{
fill: #4BC0A5;
color: #A4DFD1;
stroke:#999999;
}
</style>
</head>
<script src="d3.js"></script>
<body>
<div style="width:700px;height:300px;border:2px solid #F00;overflow-y:scroll;" style="-webkit-user-select: none;">
<svg contentScriptType="text/ecmascript" width="2000" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify" style="background-color:#000000;" contentStyleType="text/css" viewBox="0 0 2000.0 2000.0" height="2000" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" version="1.0">
<defs>
<symbol statusvalue="0" statusname="正常状态" categoryname="linefeeder" groupname="eleobj" viewBox="0 0 100.0 7.0" id="220kV母线_0" preserveAspectRatio="none meet" alisaname="220kV母线">
<defs/>
<line y2="3.543307" style="stroke:#800080;stroke-dasharray:none;stroke-width:5.3149605;" x1="0" x2="99.99921015400001" lineType="line" y1="3.543307"/>
</symbol>
<symbol statusvalue="0" statusname="正常状态" categoryname="linefeeder" groupname="eleobj" viewBox="0 0 106.0 7.0" id="500kV母线_0" preserveAspectRatio="none meet" alisaname="500kV母线">
<defs/>
<line y2="3.543307" style="stroke:#ffffb7;stroke-dasharray:none;stroke-width:5.3149605;" x1="0" lineType="line" x2="105.250391128" y1="3.543307"/>
</symbol>
</defs>
<use id="use1" typename="busb" xmlns:xlink="http://www.w3.org/1999/xlink" style="shape-rendering:auto;" transform="" width="400" xlink:show="embed" xlink:type="simple" symbolname="220kV母线" height="7" groupname="eleobj" categoryname="linefeeder" x="168" y="106" xlink:href="#220kV母线_0" xlink:actuate="onLoad"/>
<use id="use2" typename="busb" xmlns:xlink="http://www.w3.org/1999/xlink" style="shape-rendering:auto;" transform="" width="400" xlink:show="embed" xlink:type="simple" symbolname="500kV母线" height="7" groupname="eleobj" categoryname="linefeeder" x="167.99998474121094" y="144" xlink:href="#500kV母线_0" xlink:actuate="onLoad"/>
</svg>
</div>
<button id="btn" onclick="fn1()">替换use引用的symbol</button>
<button id="btn" onclick="fn1Restroe()">恢复</button></br>
<button id="btn" onclick="fn2()">修改第二条的symbol样式</button></br>
<button id="btn" onclick="fn3()">直接为use添加class使第一条220kv母线不带电,no work</button>
<button id="btn" onclick="fn4()">通过将symbol中的style中的stroke拿出来并且为use添加class使第一条220kv母线不带电,work</button></br>
<button id="btn" onclick="fn5()">通过将移除use的class使第一条220kv母线带电,no work</button>
<button id="btn" onclick="fn6()">通过将移除use的class然后将symbol中的stroke写到style中使第一条220kv母线带电,work</button>
<script>
function fn1(){
d3.select("#use1").attr("xlink:href","#500kV母线_0");
}
function fn2(){
//d3不能选中symbol元素,改用js
//alert(d3.select("#500kV母线_0"));
console.log(document.getElementById("500kV母线_0"));
var symbolNode=document.getElementById("500kV母线_0")
var childs = symbolNode.childNodes;
for(var i = childs.length - 1; i >= 0; i--) {
var child=childs.item(i);
if(child.nodeName=="line"){
console.log(child.style.stroke);
child.style.stroke="#ffffff";
console.log(child.style.stroke);
}
}
//symbol样式已经变了但是use元素并未随之更新,重新设置xlink:href后发现生效了,use元素也变成了白色
d3.select("#use2").attr("xlink:href","#500kV母线_0");
}
function fn3(){
d3.select("#use1").attr("class","uncharged");
console.log("并未能生效");
}
function fn4(){
var symbolNode=document.getElementById("220kV母线_0")
var childs = symbolNode.childNodes;
for(var i = childs.length - 1; i >= 0; i--) {
var child=childs.item(i);
if(child.nodeName=="line"){
console.log(child.style.stroke);
child.setAttribute("stroke",child.style.stroke);
child.style.stroke="";
}
}
d3.select("#use1").attr("class","uncharged");
console.log("生效了");
}
function fn5(){
d3.select("#use1").attr("class","");
console.log("并未能生效,并且发现整个引用的symbol都绘制不出来了");
//document.getElementById("use1").removeAttribute("class");
}
function fn6(){
var symbolNode=document.getElementById("220kV母线_0")
var childs = symbolNode.childNodes;
for(var i = childs.length - 1; i >= 0; i--) {
var child=childs.item(i);
if(child.nodeName=="line"){
child.style.stroke=child.getAttribute("stroke");
}
}
d3.select("#use1").attr("class","");
console.log("居然生效了");
}
function fn1Restroe(){
d3.select("#use1").attr("xlink:href","#220kV母线_0");
}
</script>
</body>
</html>
该svg中有两个use元素,第一条引用了一个紫色的220kv母线symbol,第二条引用了一个黄色的500kV母线。
1 点击第一个按钮"替换use元素引用的symbol",这个发现第一条也成了500kV母线,这里就是简单改了一个第一个use元素的xlink:href
2 点击第一个按钮"修改第二条的symbol样式",这是直线用js代码修改了500kV母线的symbol的stroke属性,注意这里修改完成必须重新设置一下use的xlink:href
3 重点来了,对于第一条母线,假如我想让它不带电的时候为灰色,这时不用再添加一个symbol,在css中直接加入了uncharged的class属性,定义了灰色,
按照常规思维,再加好css属性后,我直接为use1添加了class="uncharged"属性,发现并未生效,这时因为我定义的symbol中的<line>元素,stroke是放在style属性当中的,所有对于“直接为use添加class使第一条220kv母线不带电,no work“,因为css中的并未成覆盖stroke。所以要使用js代码将line元素的stroke属性放到外面,这时work了
4 对于恢复到原来的颜色,也不能简单的为use元素remove它的class属性,而应该把symbol中线的stroke属性写回到style中