使用JavaScript在HTML的textContent属性中插入换行(适用于IE)

3
我正在使用JavaScript生成动态SVG图像。 我的意图是让特定区域的信息包含在工具提示中。 到目前为止,我已经在Chrome和Firefox中成功实现,但在IE 11中仅部分成功。
如果我使用textContent,在IE中会忽略"\r\n",并且"
"会被显示出来。
先前提问过类似问题的答案似乎是使用innerHTML: Question 9330671 Question 9980416 通常情况下,切换到innerHTML就可以解决这个问题,但是IE不支持此特定用途的innerHTML,因此根本没有文本显示。
使用innerHTML或者textContent对于Chrome或Firefox都有效,所以这只是IE(测试过IE 11)中的问题。抱歉对于那些必须使用IE进行代码测试的人们。

交互式代码可在http://jsfiddle.net/rnhy9pus/找到。

或者,完整的代码如下:

function createPathContent(svgID, popupText, pathDirections)
{
  var path = document.createElementNS("http://www.w3.org/2000/svg","path");
  path.setAttribute("d",pathDirections);
  var popup = document.createElementNS("http://www.w3.org/2000/svg","title");
  popup.textContent = popupText; // <-- LINE TO FOCUS ON
  path.appendChild(popup);
  document.getElementById(svgID).appendChild(path);
}
function createPathHTML(svgID, popupText, pathDirections)
{
  var path = document.createElementNS("http://www.w3.org/2000/svg","path");
  path.setAttribute("d",pathDirections);
  var popup = document.createElementNS("http://www.w3.org/2000/svg","title");
  popup.innerHTML = popupText; // <-- LINE TO FOCUS ON
  path.appendChild(popup);
  document.getElementById(svgID).appendChild(path);
}
function createExample(svgID)
{
  document.getElementById(svgID).setAttribute("xmlns", "http://www.w3.org/2000/svg");
  document.getElementById(svgID).setAttribute("version", "1.1");
  document.getElementById(svgID).setAttribute("width", "300");
  document.getElementById(svgID).setAttribute("viewBox", "0 0 100 100");
  document.getElementById(svgID).setAttribute("preserveAspectRatio", "xMinYMin meet");

  var style = document.createElement("style");
  style.setAttribute("type","text/css");
  style.innerHTML = "path { fill: #ccc; } path:hover { fill: #ff0; }";
  document.getElementById(svgID).appendChild(style);

  var NEW_LINE = "\r\n";
  //var NEW_LINE = "<br />"; // This displays literally in textContent and as a new line in innerHTML.

  createPathContent(svgID, "Tooltip text using textContent:" + NEW_LINE + "New Line", "M 10 10 L 90 10 L 90 45 L 10 45 Z");
  // Works correctly in Chrome or Firefox.  Displays in IE 11, but only on a single line.

  createPathHTML(svgID,    "Tooltip text using innerHTML:"   + NEW_LINE + "New Line", "M 10 55 L 90 55 L 90 90 L 10 90 Z");
  // Works correctly in Chrome or Firefox.  Does not display in IE 11.
}

createExample("exampleSVG");
<svg id="exampleSVG" xmlns="http://www.w3.org/2000/svg"></svg>

2个回答

2
就SVG而言,innerHTML属性还没有完全实现,但已经接近了。目前Chrome和Firefox都支持该属性在Element接口上的使用,但Internet Explorer不支持。鉴于此情况,Mozilla开发者网络提供了以下警告

This is an experimental API that should not be used in production code.

Internet Explorer团队已经有一个内部工单来考虑在未来的Internet Explorer版本中添加类似的支持。在那之前,您可以通过一种方法在IE、Chrome和Firefox中实现换行。
我必须警告您; 在这个点后面有龙(我们将要做一些非标准的事情,这可能完全在未来被破坏。我们再也不会谈论这个问题了。)。
让我们从创建一个文档片段开始,其中至少有三个元素: 两行文本,由一个<br>元素分隔开来。
var fragment = document.createDocumentFragment();

fragment.appendChild(document.createTextNode("First Line\r"));
fragment.appendChild(document.createElement("br"));
fragment.appendChild(document.createTextNode("Second Line"));

接下来,让我们直接将该片段传递到createPathContent方法中:
createPathContent(svgID, fragment, "M 10 10 L 90 10 L 90 45 L 10 45 Z");

最后,让我们将该片段作为子元素添加到<title>元素中:
popup.appendChild(popupText);

以上内容提供了当您将鼠标悬停在元素上时,行为的一致表示。请注意,渲染的工具提示是一个很大程度上不可预测的东西。我们今天看到的结果可能会在未来发生变化。
示例:http://jsfiddle.net/rnhy9pus/4/

这是一份非常有益和信息丰富的回复。谢谢你。不幸的是,当我在我的简化示例中尝试了你的方法时,它可以正常工作,但是当我将其移植到我的生产代码中时,它导致所有路径对象无法呈现。显然它与我的SVG排列中的其他东西发生了冲突,但根本原因不太明显。 - Bryan
@Bryan 这说得很有道理;你需要特殊处理想保留多行的任何位置,并将其发送到不同的代码路径。如果另一种方法在不影响其他代码的情况下正常工作,那就足够好了 :) 只是高兴你暂时找到了一个足够解决问题的方法。 - Sampson

1
    function createPathContent(svgID, popupText, pathDirections)
    {
        var path = document.createElementNS("http://www.w3.org/2000/svg","path");
        path.setAttribute("d",pathDirections);
        var popup = document.createElementNS("http://www.w3.org/2000/svg","title");
     // popup.textContent = popupText; // <-- LINE TO FOCUS ON
popup.textContent=" "
//popup.firstChild.nodeValue=popupText
popup.firstChild.nodeValue='Edgar'
Node.prototype.appendChild.call(popup, document.createElement("br"))
Node.prototype.appendChild.call(popup, document.createTextNode('Allen Poe.'))
        path.appendChild(popup);
        document.getElementById(svgID).appendChild(path);
    }


每当我试图弄清楚textContent是否应该将\n(\x0A\u000A...)解释为除空格以外的任何内容时,我的头就会转。

textContent:
http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-textContent

接口Text:
http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1312295772

接口CharacterData:
http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-FF21A306

无论如何,我做了一个练习,使用一些基本原理。我希望你会像我一样受益。它会在一行上产生带有“Edgar”的工具提示,下一行是“Allen Poe.”。


function createPathContent(svgID, popupText, pathDirections)
{
    var path = document.createElementNS("http://www.w3.org/2000/svg","path");
    path.setAttribute("d",pathDirections);
    var popup = document.createElementNS("http://www.w3.org/2000/svg","title");
    //popup.textContent = popupText; // <-- LINE TO FOCUS ON

          popupText= popupText.split('\n')                                                  // note: firefox needs "\r" passed in "\r\n".
          while (true) { popup.appendChild(document.createTextNode(popupText.shift()))      // note: "" here is ok, will be appended as empty #text node
                         if (popupText.length) popup.appendChild(document.createElement("br"))
                         else break }

    path.appendChild(popup);
    document.getElementById(svgID).appendChild(path);
}

这是一个在函数内部有效的补丁。它利用了Jonathan的巧妙技巧,Firefox需要"\r",而IE和Chrome则可以使用<br>。

使用这种技术将传入数组的字符串(带"\r"条目)分解成子元素< br>元素足以让Internet Explorer暂时正常工作。非常感谢您包含补丁代码。 - Bryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接