用javascript创建<text>元素后,为什么我不能getBBox?

时间:2016-09-12 19:58:37

标签: javascript html dom svg

我有一个脚本,在现有<text>内向我的标记添加<svg>元素。在该新元素上运行getBBox()会给我一个错误。如果我在标记中包含<text>以开始并运行等效脚本,则getBBox运行时没有任何问题。 DOM是不是完全将我的js-built <text>视为文本元素......我错过了一些“写的东西”&lt; text&gt;'实际上是一个<text>“步骤?

function works() {
  console.log('start "works"')
  var svgElem = document.querySelector('.works');
  var textElem = svgElem.querySelector('text');
  var textBBox = textElem.getBBox();
  console.log(textBBox);
  console.log('end "works"')
}
works();

function doesntwork() {
  console.log('start "doesntwork"')
  var svgElem = document.querySelector('.doesntwork');
  var textElem = document.createElement("text");
  textElem.appendChild(svgElem.firstChild);
  svgElem.appendChild(textElem);
  console.log('"doesntwork" breaks after this');
  var textBBox = textElem.getBBox(); // breaks the script
  console.log(textBBox);
  console.log('end "doesntwork"')
}
doesntwork();
<svg class="doesntwork">
  not working
</svg>

<svg class="works">
  <text>
    working
  </text>
</svg>

不太通用的第二部分:

在我的完整项目中,我实际上正在转向

<div class="target">content</div>

<div class="target"><svg><text>content</text></svg></div>

使用js创建<text><svg>。这个想法基本上是

var targetElems = document.querySelectorAll('.target');
for (var i = 0; i < targetElems.length; ++i) { // for each target
    var targetElem = targetElems[i];
    var textElem = document.createElement("text"); // build a <text>
    while (targetElem.firstChild) // put the target's content (which could include child elements) in the <text>
        textElem.appendChild(targetElem.firstChild);
    var svgElem = document.createElement("svg"); // build an <svg>
    svgElem.appendChild(textElem); // put the <text> in the <svg> 
    targetElem.appendChild(svgElem); // put the <svg> in the target
    var textBBox = textElem.getBBox(); // want to be able to get the <text>'s BBox (this currently has a breaking error)
    console.log(textBBox);
}

我是否必须在每个步骤添加一个信号 - “这是<text>,这是<svg>”?

或者我是否认为整件事情错了/是否有更聪明的方法将.target > [content]转变为.target > svg > text > [content]

1 个答案:

答案 0 :(得分:3)

您应该可以使用:createElementNS

  

document.createElementNS(String namespaceURI, String qualifiedName)

     

其中:

namespaceURI = "http://www.w3.org/2000/svg"
name = "text"

这样的事情:

&#13;
&#13;
function worksnow() {
  console.log('start "worksnow"')
  var svgElem = document.querySelector('.worksnow');
  var textElem = document.createElementNS("http://www.w3.org/2000/svg", "text"); // CHANGED THIS
  textElem.appendChild(svgElem.firstChild);
  svgElem.appendChild(textElem);
  var textBBox = textElem.getBBox(); // no longer breaks the script!
  console.info(textBBox); // Gets SVGRect data.
  console.log('end "worksnow"')
}
worksnow();
&#13;
<svg class="worksnow">
  works now!
</svg>
&#13;
&#13;
&#13;

所以,在控制台中,你会得到这个:

SVG