Search code examples
javascriptsvgdom

How to add closing tags for line breaks (can't save the changes because of html standards)


I need to save my DOM structure as SVG image. To do so I transform some elements according to SVG standards. SVG demands that line break and img tag shall have closing tags.

When I try to replace them in innerHTML, it automatically converts back to html standards (without closing tag). The same when I just add closing line break tag, I just get two break tags.

Is there a way to convert it to SVG standards?

var someText1 = main.getElementsByTagName("span")[0];
someText1.innerHTML = someText1.innerHTML.replace(/<br>/g, '<br />');
console.log(someText1.innerHTML);

var someText2 = main.getElementsByTagName("span")[1];
someText2.innerHTML = someText2.innerHTML.replace(/<br>/g, '<br></br>');
console.log(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>


Solution

  • You are using replace string with .innerHTML which is work with string and when browser render out what you request, it will be just HTML (valid HTML). I'm not good to explain more about this but I suggest you to read this page because they have very well explained.

    To make your <br> to be valid SVG, I recommend you to use DOM object instead.

    First create br element into a variable.

    const brElement = document.createElementNS("http://www.w3.org/2000/svg", 'br');
    

    And then replace them. Here is full code.

    const brElement = document.createElementNS("http://www.w3.org/2000/svg", 'br');
    var someText1 = main.getElementsByTagName("span")[0];
    someText1.querySelector('br').replaceWith(brElement);
    console.log(someText1.innerHTML);
    
    var someText2 = main.getElementsByTagName("span")[1];
    someText2.querySelector('br').replaceWith(brElement);
    console.log(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>

    Once the code runned, it will be change <br> to be <br></br> and I hope that is valid SVG as you want.

    Edit: As mentioned by @Robert Longson , the br tag is not in SVG element reference it maybe invalid tag and I don't see any result from it (no new line). So, I suggest to change it to something else, or remove it instead, (or maybe keep using for some reason).