Как добавить закрывающие теги для разрывов строк (невозможно сохранить изменения из-за стандартов HTML)

Мне нужно сохранить структуру 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>

Почему бы просто не использовать div?

Normajean 02.07.2024 13:46

Просто чтобы понять вопрос. Когда вы говорите, что вам нужно сохранить изображение SVG, что это значит? И тогда проблема в том, что при использовании <br> документ SVG не является допустимым XML, верно?

chrwahl 02.07.2024 17:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
85
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы используете строку замены на .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.

Robert Longson 02.07.2024 15:24

Оно работает! Спасибо

AntonAntonoff 02.07.2024 16:43

@RobertLongson Я не уверен в этом. (Возможно, вы правы.) Я тоже не вижу никакого результата от <br></br>, но, тем не менее, я пробую то, что исходный плакат просил добавить закрывающий тег для br. 😄

vee 02.07.2024 16:48
document.createElement('br'); самый простой
Robert Longson 02.07.2024 17:23

Вы используете сериализацию 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>

Другие вопросы по теме