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

时间:2019-04-23 04:42:13

标签: javascript html 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;
}

过去几个月来它一直正常工作。几天前,出现了一个问题:在某些浏览器中,htmlToText('<br>')不再像往常一样返回'\n',而是返回{{1 }},所以:

''

在Mac Chrome版本:textToHtml(htmlToText('<br>')) // A few months ago got '<br>' // but today got '', I lost my '<br>' 和Mac Firefox版本:73.0.3683.75中,66.0.3 (64-bit)丢失了,但在Mac Safari版本:'<br>',其他版本和平台未经测试。

我确定他们几个月前的版本运行良好,并且我知道解决该问题的方法(我可以将RegExp自己的所有12.1 (14607.1.40.1.4)替换为'<br>'),我只是想知道还有其他人吗遇到同样的情况?这是浏览器中的错误吗?

2 个答案:

答案 0 :(得分:0)

MDN上显示的文档示例中,他们明确地说:

  

此示例将innerTextNode.textContent进行比较。请注意innerText如何知道<br>标签之类的内容,并忽略隐藏的元素。

现在,我已经在Firefox 66.0.3 (64bits)上对此进行了测试,并且在执行操作时,如果呈现/设置/获取属性的元素在document.body上呈现或存在,可以查看下面的两个示例:

示例1:

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`)));
.as-console {background-color:black !important; color:lime;}
<div id="test"></div>

示例2:

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`)));
.as-console {background-color:black !important; color:lime;}

而且,就像您说的那样,如果document中不存在该元素(在某些较新的浏览器上)将不起作用,但是我不知道到底是什么原因(也许这是因为您创建的元素未呈现):

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`)));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

无论如何,我已经谈到了创建元素的下一种方法,将其附加到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`)));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

其他:在the-poor-misunderstood-innerText上有关于innerText的精彩读物

答案 1 :(得分:0)

https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute中指定的作品

可以设置,以给定值替换元素的子元素,但将换行符转换为br元素。

如果我不清楚不清楚的原因,为什么会有所不同,这就是为什么我赞成,不要依赖这种行为。

我没有通过这样的反向测试的方法的示例:

assert textToHtml(htmlToText(x)) === x;