Мне нужно сохранить структуру DOM как изображение SVG. Для этого я преобразую некоторые элементы в соответствии со стандартами SVG. SVG требует, чтобы разрыв строки и тег img имели закрывающие теги.
Когда я пытаюсь заменить их в InternalHTML, он автоматически преобразуется обратно в стандарты HTML (без закрывающего тега). То же самое, когда я просто добавляю закрывающий тег разрыва строки, я получаю только два тега разрыва.
Есть ли способ преобразовать его в стандарты SVG?
var someText1 = main.getElementsByTagName("span")[0];
someText1.innerHTML = someText1.innerHTML.replace(/<br>/g, '<br />');
console.info(someText1.innerHTML);
var someText2 = main.getElementsByTagName("span")[1];
someText2.innerHTML = someText2.innerHTML.replace(/<br>/g, '<br></br>');
console.info(someText2.innerHTML);
<svg xmlns = "http://www.w3.org/2000/svg" width = "500" height = "500" viewBox = "0 0 500 500">
<foreignObject id = "main" width = "100%" height = "100%" x = "0" y = "0">
<span>one<br>two</span>
<span>three<br>four</span>
</foreignObject>
</svg>
Просто чтобы понять вопрос. Когда вы говорите, что вам нужно сохранить изображение SVG, что это значит? И тогда проблема в том, что при использовании <br>
документ SVG не является допустимым XML, верно?
Вы используете строку замены на .innerHTML
, которая работает со строкой, и когда браузер отображает то, что вы запрашиваете, это будет просто HTML (действительный HTML).
Я не умею объяснять это подробнее, но предлагаю вам прочитать эту страницу, потому что они очень хорошо объяснили.
Чтобы ваш <br>
был действительным SVG, я рекомендую вам вместо этого использовать объект DOM.
Сначала создайте элемент br
в переменной.
const brElement = document.createElementNS("http://www.w3.org/2000/svg", 'br');
А затем заменить их. Вот полный код.
const brElement = document.createElementNS("http://www.w3.org/2000/svg", 'br');
var someText1 = main.getElementsByTagName("span")[0];
someText1.querySelector('br').replaceWith(brElement);
console.info(someText1.innerHTML);
var someText2 = main.getElementsByTagName("span")[1];
someText2.querySelector('br').replaceWith(brElement);
console.info(someText2.innerHTML);
<svg xmlns = "http://www.w3.org/2000/svg" width = "500" height = "500" viewBox = "0 0 500 500">
<foreignObject id = "main" width = "100%" height = "100%" x = "0" y = "0">
<span>one<br>two</span>
<span>three<br>four</span>
</foreignObject>
</svg>
После запуска кода он изменится <br>
на <br></br>
, и я надеюсь, что это правильный SVG, как вы хотите.
Редактировать:
Как упоминал @Robert Longson, тега br
нет в ссылке на элемент SVG возможно, это недопустимый тег, и я не вижу от него никакого результата (нет новой строки). Итак, я предлагаю изменить его на что-то другое или удалить (или, возможно, по какой-то причине продолжать использовать).
br не является элементом SVG, поэтому не следует создавать его в пространстве имен SVG.
Оно работает! Спасибо
@RobertLongson Я не уверен в этом. (Возможно, вы правы.) Я тоже не вижу никакого результата от <br></br>
, но, тем не менее, я пробую то, что исходный плакат просил добавить закрывающий тег для br
. 😄
document.createElement('br');
самый простой
Вы используете сериализацию HTML, когда вам нужно использовать сериализацию XML. К счастью, в браузерах есть сериализатор XML.
var someText1 = main.getElementsByTagName("span")[0];
console.info(new XMLSerializer().serializeToString(someText1));
var someText2 = main.getElementsByTagName("span")[1];
console.info(new XMLSerializer().serializeToString(someText2));
var wholeThing = main.parentElement;
console.info(new XMLSerializer().serializeToString(wholeThing));
<svg xmlns = "http://www.w3.org/2000/svg" width = "500" height = "500" viewBox = "0 0 500 500">
<foreignObject id = "main" width = "100%" height = "100%" x = "0" y = "0">
<span>one<br>two</span>
<span>three<br>four</span>
</foreignObject>
</svg>
Проблема здесь не в том, как изменить разметку HTML или как добавить элементы в DOM, а в том, как превратить DOM в XML-документ.
Используйте XMLSerializer для получения элемента DOM и вывода строки XML:
Кстати. не забудьте использовать пространство имен HTML для элементов внутри ForeignObject.
const svgelm = document.querySelector('svg');
const s = new XMLSerializer();
let xmlstr = s.serializeToString(svgelm);
console.info(xmlstr);
<svg xmlns = "http://www.w3.org/2000/svg" width = "500" height = "500" viewBox = "0 0 500 500">
<foreignObject id = "main" width = "100%" height = "100%" x = "0" y = "0">
<span xmlns = "http://www.w3.org/1999/xhtml">one<br>two</span>
<span xmlns = "http://www.w3.org/1999/xhtml">three<br>four</span>
</foreignObject>
</svg>
Почему бы просто не использовать div?