How to change CSS class to an <use> children inside a SVG?

安稳与你 提交于 2021-01-28 21:51:08

问题


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 rectelement, 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!