innerHTML, innerText, textContent 的区别

发布:elantion 日期:2019-11-26 阅读:21 评论:0

我们要改变或获取一个DOM元素内的文本时,我们会有三个函数可以选择:innerHTML, innerText, textContent。它们之间有什么不同,我们该如何选择呢?

Element.innerHTML

这个很好理解,当向这个属性赋值时,它会把文本转换成DOM结构,例如下面:

const div = document.createElement('div');
div.innerHTML = `
    <span>text</span>
`;
document.body.appendChild(div);

就会生成这样的DOM结构:

<body>
    <div>
        <span>text</span>
    </div>
</body>

相反,如果读取其值就会把完整的DOM结构输出成字符串:

const div = document.querySelector('div');
console.log(div.innerHTML);
// 输出:<span>text</span>

Element.innerText

这个是微软早年使用的属性,并没写进w3c标准里,但现在浏览器基本都实现了该属性。它的作用跟innerHTML很相似,不一样的是,它并不会转成DOM结构,遇到html特殊字符时会对其进行转义,无论赋值还是读取。例如,向它赋值时,字符串包含html特殊字符时,就会转义:

const invisible = document.createElement('span');
invisible.style.display = 'none';
invisible.innerText = 'invisible';

const div = document.createElement('div');
div.innerText = `<span>visible</span>`;
div.appendChild(invisible);
document.body.appendChild(div);

生成的HTML是这样:

<doby>
    <div>&lt;span&gt;visible&lt/span&gt;<span style="display:none;">invisible</span></div>
</body>

当读取innerText值时,它会把DOM元素内可见的文本取出来,并且会对已经转义的HTML字符进行反转:

const div = document.queryElement('div');
console.log(div.innerText);
// 输出:<span>visible</span>

Element.textContent

最后这个跟innerText又非常相似,也会对HTML字符进行转义,不一样的是,当取它的值时,它是不管文本是否可见,只要是DOM元素内的字符都会取出来。而当对其赋值时,其行为跟innerText一模一样:

const invisible = document.createElement('span');
invisible.style.display = 'none';
invisible.innerText = 'invisible';

const div = document.createElement('div');
div.innerText = `<span>visible</span>`;
div.appendChild(invisible);
document.body.appendChild(div);

生成的HTML与innerText一模一样:

<doby>
    <div>&lt;span&gt;visible&lt/span&gt;<span style="display:none;">invisible</span></div>
</body>

但取值时就会不一样了:

const div = document.querySelector('div');
console.log(div.textContent);
// 输出:<span>visible</span>invisible

我们看到innerText需要对元素的可见性进行判断,所以按理说innerText的性能会稍微弱一点,而且不是w3c标准,所以一般情况下,如果要取DOM元素内的字符的话,我们用textContent即可。

应付xss的特殊作用

从上面可以看到,textContent和innerText会对字符里包含HTML特殊字符进行转义,所以利用这个原理,我们很方便地制造出一个消除xss攻击的函数:

const xss = (str) => {
    const tempEl = document.createElement('div');
    tempEl.textContent = str;
    return tempEl.innerHTML;
};

// usage
xss('<span>test</span>');
// 输出:&lt;span&gt;test&lt/span&gt;

这个函数不仅安全,性能也极其优秀,不访在项目使用哦。