简析
这几个属性都是原生 JS 用来获取和设置 DOM 节点的内容的,但是获取的内容格式和范围却有一些不同。
对比一
先上一段代码
1 2 3 4 5 6 7 | <!- HTML --> <div id="test"> <span style="color:red">test1</span> test2 </div> <!- JS --> var elementNode = document.getElementById('test'); |
innerHTML
获取或设置从对象的起始位置到终止位置的全部内容,包括 Html 标签
1 | elementNode.innerHTML; // <span style="color:red">test1</span> test2 |
innerText
获取或设置从起始位置到终止位置的内容, 但是不含 Html 标签
1 | elementNode.innerText; // test1 test2 |
可以看到,该例子中的 innerHTML 获取到的是含有 HTML 标签的内容,而 innerText 获取的内容不含有 HTML 标签的文本。
outerHTML
获取或设置除了包含 innerHTML 的全部内容外, 还包含对象标签本身
1 | elementNode.outerHTML; // <div id="test"> <span style="color:red">test1</span> test2 </div> |
outerText
获取或设置从起始位置到终止位置的内容, 还包含对象标签本身, 但是不含 Html 标签
1 | elementNode.outerText; // test1 test2 |
小结
1)innerHTML 与 outerHTML 在设置对象的内容时包含的 HTML 会被解析,但 innerText 与 outerText 则不会转义 HTML 内容,而是按照文本直接输出 HTML 标签。
2)在设置时,innerHTML 与 innerText 仅设置标签内的文本,而 outerHTML与 outerText 设置包括标签在内的文本。
3)innerHTML 是符合W3C标准的属性,而 innerText 只适用于IE浏览器。
对比二
textContent
获取或设置从起始位置到终止位置的内容, 还包含对象标签本身, 但是不含 Html 标签
textContent 与 innerText
区别一
继续再上例子
1 2 3 4 5 6 7 8 | <!- HTML --> <div id="test2"> <span>test1</span> <span>test2</span> </div> <!- JS --> var elementNode2 = document.getElementById('test2'); |
分别用 textContent 与 innerText 来获取节点的内容,结果如下
1 2 3 4 5 6 7 | elementNode2.textContent; /* test1 test2 */ elementNode2.innerText; // test1 test2 |
可以看到,innerText 输出结果是在和页面中显示是一样的在同一行显示,而 textContent 输出结果和代码中的显示是一致的。当然我们也可以把代码改成下面这样,来看看是不是真的跟前面说的一样。
1 2 3 4 5 6 7 8 9 | <!- HTML --> <div id="test2"> <span>test1</span><span>test2</span> </div> <!- JS --> var elementNode2 = document.getElementById('test2'); elementNode2.textContent; // test1test2 elementNode2.innerText; // test1test2 |
是吧。这次 innerText 输出结果是在和页面中显示也是一样。textContent 输出结果和代码中的显示也是一致的。
可以这样总结:innerText 的值决定于浏览器的显示结果,textContent 的值决定于代码的结构。
区别二
再来看一个例子
1 2 3 4 5 6 7 8 9 | <!- HTML --> <div id="test3"> <span>test1</span> <span style="display: none;">test2</span> <script>var a='test3';</script> </div> <!- JS --> var elementNode3 = document.getElementById('test3'); |
这里我们再分别用 textContent 与 innerText 来获取节点的内容,看看结果如何?
1 2 3 4 5 6 7 8 | elementNode3.textContent; /* test1 test2 var a='test3'; */ elementNode3.innerText; // test1 |
textContent 可以获取到一个元素之间包含了 script 标签或者 style.display 的值为 none 标签,innerText 是获取不到这些文本的。再一次验证“ innerText 的值决定于浏览器的显示结果”这个总结。
区别三
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!- HTML --> <div id="test4"> test1 <span></span> test2 <p></p> test3 <span></span> <span></span> <span></span> test4 <p></p> <p></p> <p></p> test5 </div> <!- JS --> var elementNode4 = document.getElementById('test4'); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | elementNode3.textContent; /* test1 test2 test3 test4 test5 */ elementNode3.innerText; /* test1 test2 test3 test4 test5 */ |
textContent 会把空标签解析成换行(几个空标签就是几行),innerText 只会把 block 元素类型的空标签解析换行,并且如果是连续多个的话仍看成是一个,而 inline 类型的元素则解析成空格,同样也是连续多个算成一个。
区别四
innerText 和 textContent 两个属性并非 html5 的规范属性,它们是各个浏览器厂商自己实现的,那么也就是说有些浏览器实现了innerText,有些浏览器实现了 textContent ,有些浏览器两个属性都有实现,因此书写的时候就要考虑到兼容性判断了,可以参考这样写:
1 2 3 4 5 | if(el.textContent){ el.textContent='test'; }else{ el.innerText='test'; } |
另外,还需要我们注意的是,innerText 的操作一定会引起浏览器回流,所以是比较耗性能的。而 textContent 并非一定会触发回流,但它也是在特定情况下(比如所赋值的内容超出了容器尺寸,影响到了页面整体布局)才会触发回流,在其他情况下一般只是触发浏览器的重绘。
恭喜你,阅读完毕~