深入理解javascript描述元素内容的5个属性

×

目录

[1]innerHTML [2]outerHTML [3]innerText[4]outerText[5]textContent

前面的话

<p>This is a <i>simple</i> document</p>

  上面这行代码中,<p>元素的内容是什么呢?答案一:内容是HTML字符串"This is a <i>simple</i> document";答案二:内容是纯文本字符串"This is a simple document";答案三:内容是一个Text文本节点、一个包含了Text文本子节点的Element元素节点和另外一个Text文本节点

  三个答案都正确,不同的答案从不同的角度描述了元素内容。本文将详细介绍描述元素内容的5个属性

innerHTML

  innerHTML属性可读可写。在读模式下,返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的HTML标记;在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点

  [注意]IE8-浏览器会将所有标签转换成大写形式,且不包含空白文本节点;而其他浏览器则原样返回

<p id="test">This is a <i>simple</i> document</p>
<script>
console.log(test.innerHTML);//‘This is a <i>simple</i> document‘
test.innerHTML = 123;
console.log(test.innerHTML);//‘123‘
</script>

  如果将innerHTML属性设为空,等于删除所有它包含的所有节点

<p id="test">This is a <i>simple</i> document</p>
<script>
test.innerHTML = ‘‘;
console.log(test.childNodes.length);//0
</script>

  [注意]在IE9-浏览器中,不支持innerHTML的属性有:<col>、<colgroup>、<frameset>、<head>、<html>、<style>、<table>、<tbody>、<thead>、<tfoot>、<tr>。在IE8-浏览器中<title>元素也没有该属性

<table id="test"></table>
<script>
test.innerHTML = ‘1‘
//在IE9-浏览器中报错,其他浏览器返回1
console.log(test.innerHTML);
</script>

  无论什么时候,只要使用innerHTML从外部插入HTML,都应该首先以可靠的方式处理HTML。IE浏览器提供了window.toStaticHTML()方法,这个方法接收一个参数,即一个HTML字符串;返回一个经过无害处理后的版本——从源HTML中删除所有脚本节点和事件处理程序属性

var text = "<a href=‘#‘ onclick = ‘alert(\"hi\");‘>Click Me</a>";
var sanitized = window.toStaticHTML(text);
//只有IE支持
console.log(sanitized);//<a href="#">Click Me</a>

效率

  在元素上设置innerHTML属性调用了Web浏览器的解析器,通常设置innerHTML效率非常髙,甚至在指定的值需要解析时效率也是相当不错

<ul id="test1"></ul>
<ul id="test2"></ul>
<script>
console.time("time");
for(var i = 0; i < 10000;i++){
    var oLi = document.createElement(‘li‘);
    test1.appendChild(oLi);
}
//15.842ms
console.timeEnd(‘time‘);
/****************************/
console.time("time");
var sHtml = ‘‘;
for(var i = 0; i < 10000; i++){
    sHtml += ‘<li></li>‘;
}
test2.innerHTML = sHtml;
//5.373ms
console.timeEnd(‘time‘);
</script>

  从上面可以看出,使用innerHTML比appendChild()的性能高出不少

  [注意]对innerHTML属性用“+=”操作符重复追加一小段文本通常效率低下,因为它既要序列化又要解析

<ul id="test"></ul>
<script>
console.time("time");
for(var i = 0; i < 10000; i++){
    test.innerHTML += ‘<li></li>‘;
}
//time: 50416.330ms
console.timeEnd(‘time‘);
</script>

  可以看出,对innerHTML属性使用‘+=‘操作符的性能严重低下,所以一定不要这么使用

outerHTML

  outerHTML同样可读可写,与innerHTML相比,它包含被查询元素的开始和结束标签。在读模式下outerHTML返回调用它的元素及所有子节点的HTML标签;在写模式下,outerHTML会根据指定的HTML字符串创建新的DOM子树,然后用这个DOM子树完全替换调用元素

  [注意]IE8-浏览器会将所有标签转换成大写形式,且不包含空白文本节点;而其他浏览器则原样返回

<p id="test">This is a <i>simple</i> document</p>
<script>
console.log(test.outerHTML);//<p id="test">This is a <i>simple</i> document</p>
test.outerHTML = ‘<div id="test"></div>‘;
console.log(test.outerHTML);//‘<div id="test"></div>‘
</script>

innerText

  innerText属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过innerText读取值时,它会按照由浅入深地顺序,将子文档树中的所有文本拼接起来。在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点

<p id="test">This is a <i>simple</i> document</p>
<script>
console.log(test.innerText);//‘This is a simple document‘
test.innerText = ‘<div id="test"></div>‘;
console.log(test.innerText);//‘<div id="test"></div>‘
//即使在innerText中设置元素节点,最终也只是作为字符串内部的文本显示
console.log(test.childNodes[0].nodeType);//3
</script>

  因此,设置innerText属性只会生成当前节点的一个子文本节点Text。因此,可以利用将innerText设置为等于innerText来去掉所有HTML标签

<p id="test">This is a <i>simple</i> document</p>
<script>
console.log(test.innerHTML);//‘This is a <i>simple</i> document‘
test.innerText = test.innerText;
console.log(test.innerHTML);//‘This is a simple document‘
</script>

outerText

  在读取文本值时,outerText与innerText的结果完全一样,但在写模式下,outerText不只是替换调用它的元素的子节点,而是会替换整个元素

<p id="test">This is a <i>simple</i> document</p>
<script>
console.log(test.outerText);//‘This is a simple document‘
test.outerText = ‘123‘;
console.log(document.body.childNodes[0]);//‘  123‘
//报错,因为<p>元素已经被替换为‘123‘,不再存在了
console.log(test.outerText);
</script>

textContent

  textContent属性与innerText属性类似,该属性可读写。在读模式下,返回当前节点和它的所有后代节点的文本内容;在写模式下,结果会删除元素的所有子节点,插入包含相应文本值的文本节点

  [注意]IE8-浏览器不支持该属性

<p id="test">This is a <i>simple</i> document</p>
<script>
console.log(test.textContent);//‘This is a simple document‘
test.textContent = ‘<div id="test"></div>‘;
console.log(test.textContent);//‘<div id="test"></div>‘
//即使在textContent中设置元素节点,最终也只是作为字符串内部的文本显示
console.log(test.childNodes[0].nodeType);//3
</script>

  与innerText不同的是,textContent属性不仅属于元素节点ElementNode,而是属于所有节点Node

<p id="test">This is a <i>simple</i> document</p>
<script>
var oText = test.childNodes[0];
console.log(oText.textContent);//‘This is a ‘
console.log(oText.innerText);//undefined
</script>

最后

  在firefox以前的版本中不支持innerText和outerText,但是随着firefox的更新换代,这两个属性也开始支持。所以,上面的5个属性的兼容问题都来源于IE8-浏览器。IE8-浏览器不支持textContent属性,IE8-浏览器在使用innerHTML和outerHTML属性时,会将所有标签转换成大写形式,且不包含空白文本节点

  上面5个属性中,常用的是innerHTML、outerHTML和innerText这3个

时间: 2024-10-16 14:39:43

深入理解javascript描述元素内容的5个属性的相关文章

深入理解javascript对象系列第三篇——神秘的属性描述符

× 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值.是否可配置.是否可修改以及是否可枚举.本文就来介绍对象中神秘的属性描述符 描述符类型 对象属性描述符的类型分为两种: 数据属性和访问器属性 数据属性 数据属性(data property)包含一个数据值的位置,在这个位置可以读取和写入值.数据属性有4个特性 [1]Configurable(可配置性

深入理解javascript选择器API——4种元素选择器

× 目录 [1]id属性 [2]标签名 [3]name属性[4]all 前面的话 说到最常见的DOM应用,恐怕就要数取得特定的某个或某组元素的引用了.DOM定义了许多方式来选取元素,包括getElementById().getElementsByTagName().getElementsByName()和document.all()4种.接下来,将对这4种方法进行详细介绍 getElementById() 任何HTML元素可以有一个id属性,在文档中该值必须唯一 [注意]若浏览器中出现多个id名

深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点(转)

才华横溢的Stoyan Stefanov,在他写的由O’Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会是件很美妙的事情.具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以

深入理解JavaScript系列(24):JavaScript与DOM(下)

介绍 上一章我们介绍了JavaScript的基本内容和DOM对象的各个方面,包括如何访问node节点.本章我们将讲解如何通过DOM操作元素并且讨论浏览器事件模型. 本文参考:http://net.tutsplus.com/tutorials/javascript-ajax/javascript-and-the-dom-lesson-2/ 操作元素 上一章节我们提到了DOM节点集合或单个节点的访问步骤,每个DOM节点都包括一个属性集合,大多数的属性都提供为相应的功能提供了抽象.例如,如果有一个带有

深入理解JavaScript系列(15):函数(Functions)

介绍 本章节我们要着重介绍的是一个非常常见的ECMAScript对象——函数(function),我们将详细讲解一下各种类型的函数是如何影响上下文的变量对象以及每个函数的作用域链都包含什么,以及回答诸如像下面这样的问题:下面声明的函数有什么区别么?(如果有,区别是什么). 原文:http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/ var foo = function () { ... }; 平时的惯用方式: function fo

深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)

本篇是ECMA-262-3 in detail系列的一个概述(本人后续会翻译整理这些文章到本系列(第11-19章).每个章节都有一个更详细的内容链接,你可以继续读一下每个章节对应的详细内容链接进行更深入的了解. 适合的读者:有经验的开发员,专业前端人员. 原作者: Dmitry A. Soshnikov 发布时间: 2010-09-02 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ 参考1:http://ued.ctr

深入理解JavaScript系列(18):面向对象编程之ECMAScript实现(推荐)

介绍 本章是关于ECMAScript面向对象实现的第2篇,第1篇我们讨论的是概论和CEMAScript的比较,如果你还没有读第1篇,在进行本章之前,我强烈建议你先读一下第1篇,因为本篇实在太长了(35页). 英文原文:http://dmitrysoshnikov.com/ecmascript/chapter-7-2-oop-ecmascript-implementation/ 注:由于篇幅太长了,难免出现错误,时刻保持修正中. 在概论里,我们延伸到了ECMAScript,现在,当我们知道它OOP

深入理解javascript 中的 delete(转)

在这篇文章中作者从<JavaScript面向对象编程指南>一书中关于 delete 的错误讲起,详细讲述了关于 delete 操作的实现, 局限以及在不同浏览器和插件(这里指 firebug)中的表现. 下面翻译其中的主要部分. ...书中声称 “函数就像一个普通的变量那样——可以拷贝到不同变量,甚至被删除” 并附上了下面的代码片段作为说明: >>> var sum = function(a, b) {return a+b;}; >>> var add =

深入理解行内元素的布局

前言 总括: 本文通过实例讲解CSS中最大的难点之一,行内元素的布局,主要是挖掘line-height和vertical-align两个属性在布局方面的使用. 原文博客地址:深入理解行内元素的布局 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 白茶清欢无别事,我在等风,也在等你.? 正文 讲道理line-height和vertical-align 这对基是十分低调的,日常开发中碰到的很多莫名其妙的bug很大一部分都