有趣的“<br>”在innerHTML和innerText之间的转换

fen*_*ian 6 html javascript dom

我的项目中有一些非常简单的代码,如下所示:

const textToHtml = (text) => {
   const div = document.createElement('div');
   div.innerText = text;
   return div.innerHTML;
}

const htmlToText = (html) => {
   const div = document.createElement('div');
   div.innerHTML = html;
   return div.innerText;
}
Run Code Online (Sandbox Code Playgroud)

这几个月一直正常工作。 前几天,出现了一个问题:在某些浏览器中htmlToText('<br>')不再'\n'像往常一样返回'',而是返回,因此:

textToHtml(htmlToText('<br>'))
// A few months ago got '<br>'
// but today got '', I lost my '<br>'
Run Code Online (Sandbox Code Playgroud)

在 Mac Chrome version:73.0.3683.75和 Mac Firefox version:66.0.3 (64-bit)'<br>'丢失,但在 Mac Safari version: 中没有12.1 (14607.1.40.1.4),其他版本和平台未测试。

我肯定他们在几个月前的版本运作良好,我知道变通方法来解决这个问题(我可以取代所有'<br>''\n'通过正则表达式我自己),我只是想知道有其他人遇到同样的情况?这是浏览器中的错误吗?

Shi*_*rsz 3

MDN文档中有一个示例比较innerTexttextContent,其中明确指出:

这个例子innerTextNode.textContent. 请注意如何innerText了解<br>标签之类的内容,并忽略隐藏元素。

因此,我已经对此进行了测试,Firefox 66.0.3 (64bits)如果您设置/获取属性的元素在document.body您执行操作时呈现或存在,它仍然有效。您可以检查接下来的两个示例:

示例 1: div元素已存在于document.body

const textToHtml = (text) => {
   const div = document.getElementById('test');
   div.innerText = text;
   return div.innerHTML;
}

const htmlToText = (html) => {
   const div = document.getElementById("test");
   div.innerHTML = html;
   console.log("Note <br> is parsed to \\n =>", div.innerText);
   return div.innerText;
}

console.log("Output =>", textToHtml(htmlToText(`Some<br>Other`)));
Run Code Online (Sandbox Code Playgroud)
.as-console {background-color:black !important; color:lime;}
Run Code Online (Sandbox Code Playgroud)
<div id="test"></div>
Run Code Online (Sandbox Code Playgroud)

示例 2: div元素动态附加到document.body

const textToHtml = (text) => {
   const div = document.createElement('div');
   document.body.append(div);
   div.innerText = text;
   return div.innerHTML;
}

const htmlToText = (html) => {
   const div = document.createElement('div');
   document.body.append(div);
   div.innerHTML = html;
   console.log("Note <br> is parsed to \\n =>", div.innerText);
   return div.innerText;
}

console.log("Output =>", textToHtml(htmlToText(`Some<br>Other`)));
Run Code Online (Sandbox Code Playgroud)
.as-console {background-color:black !important; color:lime;}
Run Code Online (Sandbox Code Playgroud)

而且,就像你说的,如果该元素不存在于 上,它将无法工作(在某些较新的浏览器上)document,但是我不知道它到底是什么原因(也许是因为你创建的元素是未渲​​染):

示例 3: div元素不存在于document.body

const textToHtml = (text) => {
   const div = document.createElement('div');
   div.innerText = text;
   return div.innerHTML;
}

const htmlToText = (html) => {
   const div = document.createElement('div');
   div.innerHTML = html;
   console.log("Note <br> isn't parsed to \\n =>", div.innerText);
   return div.innerText;
}

console.log("Output =>", textToHtml(htmlToText(`Some<br>Other`)));
Run Code Online (Sandbox Code Playgroud)
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Run Code Online (Sandbox Code Playgroud)

不管怎样,我已经采用了下一种方法,即创建一个div元素,将其附加到body然后removes它。这样,您将不会有任何视觉干扰,并且应该适用于所有浏览器:

新实施:

const textToHtml = (text) => {
   const div = document.createElement('div');
   document.body.append(div);
   div.innerText = text;
   const html = div.innerHTML;
   div.remove();
   return html;
}

const htmlToText = (html) => {
   const div = document.createElement('div');
   document.body.append(div);
   div.innerHTML = html;
   const text = div.innerText;
   div.remove();
   return text;
}

console.log("Output =>", textToHtml(htmlToText(`Some<br>Other`)));
Run Code Online (Sandbox Code Playgroud)
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Run Code Online (Sandbox Code Playgroud)

额外:innerText关于the-poor-misunderstood-innerText有一篇很好的文章