问题
I am making and animation the objetive is change the xlink:href
inside a SVG. (this is for change a shape), and change class respect to their position inside.
This is my SVG
<svg viewBox="-20 -20 600 200" id="main">
<defs id="test">
<rect width="80" height="80" id="circle" fill="red" class="first" />
<rect width="80" height="80" id="square" fill="pink" class="second" />
<rect width="80" height="80" id="cross" fill="blue" class="third" />
</defs>
<g id="load-area">
<use x="0" xlink:href="#circle" />
<use x="100" xlink:href="#square" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
The class in every rect
element, has a different animation-delay
according to position (first execute at 0s, second at 2s, third at 4s and so on).
With JS I change every <use>
at #load-area
main.children['load-area'].children[0].setAttribute("xlink:href", getFigure(random()));
And it works, the shape changes but, suppose when it gets three times the id #cross
then all elements have third
CSS class.
I need change CSS class
inside every children of <use>
, How can I do that?
Below an element tree :
I get all <use>
with: main.children['load-area'].children
but it does not have child element, as I show u below:
回答1:
You can solve this using CSS variables that you combine with nth-child
selector and you no more need the classes.
Here is a basic example
rect {
animation:change 3s var(--d,0s) infinite;
}
@keyframes change {
0% {
opacity:1;
}
33%,100% {
opacity:0;
}
}
#load-area > use:nth-child(1) {--d:0s}
#load-area > use:nth-child(2) {--d:1s}
#load-area > use:nth-child(3) {--d:2s}
/*#load-area > use:nth-child(N) {--d:Xs}*/
<svg viewBox="-20 -20 600 200" id="main">
<defs id="test">
<rect width="80" height="80" id="circle" fill="red" />
<rect width="80" height="80" id="square" fill="pink" />
<rect width="80" height="80" id="cross" fill="blue" />
</defs>
<g id="load-area">
<use x="0" xlink:href="#circle" />
<use x="100" xlink:href="#square" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
<svg viewBox="-20 -20 600 200" id="main">
<g id="load-area">
<use x="0" xlink:href="#square" />
<use x="100" xlink:href="#circle" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
If the number is unknown or very big you can easily use a JS loop:
var e = document.querySelectorAll('#load-area use');
for(var i=0;i<e.length;i++) {
e[i].style.setProperty('--d',i+"s");
}
rect {
animation:change 3s var(--d,0s) infinite;
}
@keyframes change {
0% {
opacity:1;
}
33%,100% {
opacity:0;
}
}
<svg viewBox="-20 -20 600 200" id="main">
<defs id="test">
<rect width="80" height="80" id="circle" fill="red" />
<rect width="80" height="80" id="square" fill="pink" />
<rect width="80" height="80" id="cross" fill="blue" />
</defs>
<g id="load-area">
<use x="0" xlink:href="#circle" />
<use x="100" xlink:href="#square" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
回答2:
document.getElementsByTagName("use")[0].setAttribute("xlink:href", "#circle");
element.setAttribute(attributename, attributevalue)
Here is how you can change element attributes
来源:https://stackoverflow.com/questions/63203286/how-to-change-css-class-to-an-use-children-inside-a-svg