【问题标题】:After creating a <text> element with javascript, why can't I getBBox?用 javascript 创建 <text> 元素后,为什么我不能 getBBox?
【发布时间】:2017-01-20 08:07:17
【问题描述】:

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

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创建&lt;text&gt;&lt;svg&gt;。这个想法基本上是

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);
}

我是否必须在每个步骤添加一个信号 - “这是&lt;text&gt;,这是&lt;svg&gt;”?

还是我把整个事情都搞错了/有没有更聪明的方法可以将.target &gt; [content] 变成.target &gt; svg &gt; text &gt; [content]

【问题讨论】:

    标签: javascript html dom svg


    【解决方案1】:

    您应该可以使用:createElementNS

    document.createElementNS(String namespaceURI, String qualifiedName).

    地点:

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

    类似这样的:

    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();
    <svg class="worksnow">
      works now!
    </svg>

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

    【讨论】:

    • 太棒了,这正是我需要的。谢谢! Fwiw,以防任何未来的人想知道,当我将createElementNS 用于&lt;text&gt;&lt;svg&gt; 时,我的完整示例有效
    • 不客气。是的,如果您需要创建 any svg 标签,请始终使用:createElementNS 。感谢您的编辑。
    猜你喜欢
    • 1970-01-01
    • 2019-12-20
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 2021-01-12
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多