Как мне именованный элемент в документе SVG?

#svg

#svg

Вопрос:

Я пытаюсь определить a tspan в начале документа SVG, чтобы его можно было позже включить в a text . По крайней мере, в Firefox следующий код не дает такого результата.

 <svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <tspan id="transcluded-text">This is a text</tspan>
    </defs>
    <text>
        <use href="#transcluded-text"/>
    </text>
</svg>
 

Используя инструмент проверки Firefox, use элемент содержит теневой DOM ( #shadow-root ), как и ожидалось, но сам теневой DOM пуст.

Можно ли без использования Javascript преобразовать a tspan внутри a text подобным образом?

Комментарии:

1. Вы этого не делаете. Элемент <use> не является допустимым дочерним элементом элемента <text>.

Ответ №1:

Текстовый элемент может содержать только дочерние элементы текстового содержимого (so, not <use> ), и единственным элементом, связанным с текстом, который может содержать элемент defs, является <text> . Итак, все указывает на то, что <tspan> его нельзя использовать таким образом.

 <svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <text x="10" y="20" font-size="20" id="transcluded-text">This is a text</text>
  </defs>
  <use href="#transcluded-text"/>
</svg> 

Ответ №2:

Поскольку вы не можете использовать <use> элементы внутри <text> элемента;
или пустой <tspan> внутри <defs>

Современный собственный веб-компонент может выполнять работу по замене:

(это вызовет проблему, с которой вы, возможно, захотите разобраться)

 <script>
  customElements.define("svg-use-replacer", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => { // make sure SVG is parsed
        this.querySelectorAll('use').forEach(use => {
          let href  = use.getAttribute("href");
          let tspan = this.querySelector(href);
          use.replaceWith(tspan); // .replaceWith was not available in IE
        });
        // if the bare <svg> is required in the DOM:
        // this.replaceWith(this.querySelector("svg"));
      });
    }
  });
</script>

<svg-use-replacer>
  <svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <tspan id="foo" stroke="green">Wonderful</tspan>
    </defs>
    <text x="10" y="20" font-size="20">
      Hello
      <use href="#foo" /> Web Component
    </text>
  </svg>
</svg-use-replacer> 

Примечания

  • Олдскульный способ — присоединить класс и после анализа этого элемента запустить для него JavaScript.
  • Для веб-компонентов совершенно не имеет значения, КОГДА определен веб-компонент.
    Вы можете выполнить вышеуказанное script в любое удобное для вас время.