最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I make SVG text editable? - Stack Overflow

programmeradmin2浏览0评论

I have a text tag that I'm adding to SVG via JS script and would like to make that text editable.

Found a couple of solutions on StackOverflow:

  1. creating a css class and applying it to my SVG text element. This works perfectly, at least in Safari, but isn't remended it by MDN Here is the class that is actually someone's answer, unfortunately I can't remember whose:

    .editable {
        font-size: 0.3em;
        user-modify: read-write;
        -moz-user-modify: read-write;
        -webkit-user-modify: read-write;
    }
    
  2. wrapping the svg in a contenteditable div (answer given by Erik). This also works but results in bad cursor behavior, at least in Safari.

<div contenteditable="true">
  <svg id="svgArea" viewBox="0 0 200 200" xmlns="">
  </svg>
</div>

I have a text tag that I'm adding to SVG via JS script and would like to make that text editable.

Found a couple of solutions on StackOverflow:

  1. creating a css class and applying it to my SVG text element. This works perfectly, at least in Safari, but isn't remended it by MDN https://developer.mozilla/en-US/docs/Web/CSS/user-modify Here is the class that is actually someone's answer, unfortunately I can't remember whose:

    .editable {
        font-size: 0.3em;
        user-modify: read-write;
        -moz-user-modify: read-write;
        -webkit-user-modify: read-write;
    }
    
  2. wrapping the svg in a contenteditable div (answer given by Erik). This also works but results in bad cursor behavior, at least in Safari.

<div contenteditable="true">
  <svg id="svgArea" viewBox="0 0 200 200" xmlns="http://www.w3/2000/svg">
  </svg>
</div>

The JS part

function foo(x, y, w, h) {
  var rect, group;
  var svgPlace = document.getElementById('svgArea');
  var xmlns = "http://www.w3/2000/svg";
  group = document.createElementNS(xmlns, 'g');
  svgPlace.appendChild(group);

  var txtElem = document.createElementNS(xmlns, 'text');
  txtElem.setAttributeNS(null, 'x', x);
  txtElem.setAttributeNS(null, 'y', y * 1.25);
  txtElem.setAttributeNS(null, 'fill', 'LightBlue');
  txtElem.setAttributeNS(null, 'contentEditable', true); //does nothing!
  txtElem.setAttributeNS(null, 'class', 'editable'); //this is the best working option at the moment
  var txtVal = document.createTextNode('test');
  txtElem.appendChild(txtVal);
  group.appendChild(txtElem);
}

I'd love to be able to set the contentEditable as an attribute, if that's possible. But most importantly, what's the best way to make SVG text editable?

Share Improve this question edited Mar 30, 2019 at 10:09 Masoud Keshavarz 2,2449 gold badges40 silver badges49 bronze badges asked Mar 29, 2019 at 21:30 a_visitora_visitor 631 silver badge9 bronze badges 4
  • document.getElementById("element").contentEditable = "true"; You can also use the ref contenteditable="true" in an HTML element like so: <div contenteditable="true">. – ABC Commented Mar 29, 2019 at 21:40
  • In your second example, you have no text element to edit.. – Keith Commented Mar 29, 2019 at 21:56
  • Raymond, The <div contenteditable="true"> wrapped around <svg> works but produces odd cursor behavior. I can't get setting contentEditable to 'true' to work. This is what I tried, am I doing it wrong?: document.getElementsByTagName("text")[0].contentEditable='true' – a_visitor Commented Mar 29, 2019 at 21:56
  • The text element is added via JS to the SVG element in the second code part. – a_visitor Commented Mar 29, 2019 at 22:00
Add a ment  | 

2 Answers 2

Reset to default 2

@Raymond ment is the correct answer but since you still have problem I wrote down an example.

document.getElementById("svgWrapper").contentEditable = "true";
<div id="svgWrapper">
  <svg id="svgArea" viewBox="0 0 200 200" xmlns="http://www.w3/2000/svg">
  </svg>
</div>

I ended up solving this by placing an input tag inside a foreign object, which is added to an SVG group. That works on Safari so I wanted to post it here, in case anyone else is struggling with the same thing.

<svg>
<g>
<foreignobject>
<input></input>
</foreignobject>
</g>
</svg>

If you need to add using JS:

function addSvg(x, y, w, h) {
var rect, group;
var svgPlace = document.getElementById('svgArea');
var xmlns = "http://www.w3/2000/svg";
group = document.createElementNS(xmlns, 'g');
svgPlace.appendChild(group);

// solution
let foreigner = document.createElementNS(xmlns, "foreignObject");
foreigner.setAttributeNS(null, "x", x);
foreigner.setAttributeNS(null, "y", y);
foreigner.setAttributeNS(null, "width", w);
foreigner.setAttributeNS(null, "height", h);
group.appendChild(foreigner);

let txt = document.createElement('input');
foreigner.appendChild(txt);

}

发布评论

评论列表(0)

  1. 暂无评论