Как изменить класс CSS на <use>детей внутри SVG? - PullRequest
1 голос
/ 01 августа 2020

Я делаю анимацию, цель - изменить xlink:href внутри SVG. (это для изменения формы) и измените класс в зависимости от их положения внутри.

Это мой 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>

Класс в каждом элементе rect имеет другой animation-delay в соответствии с позицией (сначала выполняется с 0, второй с 2, третий с 4 и т. Д.).

С JS я меняю каждые <use> на #load-area

main.children['load-area'].children[0].setAttribute("xlink:href", getFigure(random()));

И это работает, форма меняется, но, предположим, когда он получает в три раза больше id #cross, тогда все элементы имеют third CSS класс.

Мне нужно изменить CSS class внутри каждого дочернего элемента <use>, как я могу это сделать?

Ниже дерева элементов:

enter image description here

I get all with: main.children['load-area'].children but it does not have child element, as I show u below:

введите описание изображения здесь

Ответы [ 2 ]

1 голос
/ 01 августа 2020

Вы можете решить эту проблему, используя CSS переменные, которые вы комбинируете с nth-child селектором, и вам больше не нужны классы.

Вот базовый c пример

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>

Если номер неизвестен или очень велик, вы можете легко использовать JS l oop:

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>
0 голосов
/ 01 августа 2020
document.getElementsByTagName("use")[0].setAttribute("xlink:href", "#circle");

element.setAttribute (attributename, attributevalue)

Вот как вы можете изменить атрибуты элемента

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...