深入理解javascript描述元素内容的5个属性
前面的话
<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>
【兼容】
在早期的firefox浏览器中不支持innerText属性,有下列兼容代码
if(!'innerText' in document.body){
HTMLElement.prototype.__defineGetter__('innerText',function(){
return this.textContent;
});
HTMLElement.prototype.__defineSetter__('innerText',function(s){
return this.textContent = s;
});
}
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个

深入理解javascript描述元素内容的5个属性的更多相关文章
- javascript中元素的scrollLeft和scrollTop属性说明
再说意义之前,前说一下这两个属性的适用范围: 注意:这两个属性只能用于元素设置了overflow的css样式中.否者这两个属性没有任何意义.且overflow的值不能为visible,但可以为hidd ...
- 深入学习jQuery描述文本内容的3个方法
× 目录 [1]html() [2]text() [3]val()[4]总结 前面的话 在javascript中,描述元素内容有5个属性,分别是innerHTML.outerHTML.innerTex ...
- 深入理解javascript对象系列第三篇——神秘的属性描述符
× 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...
- 深入理解javascript选择器API系列第一篇——4种元素选择器
× 目录 [1]id属性 [2]标签名 [3]name属性[4]all 前面的话 说到最常见的DOM应用,恐怕就要数取得特定的某个或某组元素的引用了.DOM定义了许多方式来选取元素,包括getElem ...
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 2011-12-28 23:00 by 汤姆大叔, 139489 阅读, 119 评论, 收藏, 编辑 才华横溢的 ...
- 深入理解JavaScript系列(24):JavaScript与DOM(下)
介绍 上一章我们介绍了JavaScript的基本内容和DOM对象的各个方面,包括如何访问node节点.本章我们将讲解如何通过DOM操作元素并且讨论浏览器事件模型. 本文参考:http://net.tu ...
- 深入理解JavaScript系列(18):面向对象编程之ECMAScript实现(推荐)
介绍 本章是关于ECMAScript面向对象实现的第2篇,第1篇我们讨论的是概论和CEMAScript的比较,如果你还没有读第1篇,在进行本章之前,我强烈建议你先读一下第1篇,因为本篇实在太长了(35 ...
- 深入理解JavaScript系列(16):闭包(Closures)
介绍 本章我们将介绍在JavaScript里大家经常来讨论的话题 —— 闭包(closure).闭包其实大家都已经谈烂了.尽管如此,这里还是要试着从理论角度来讨论下闭包,看看ECMAScript中的闭 ...
- 深入理解JavaScript系列(15):函数(Functions)
介绍 本章节我们要着重介绍的是一个非常常见的ECMAScript对象——函数(function),我们将详细讲解一下各种类型的函数是如何影响上下文的变量对象以及每个函数的作用域链都包含什么,以及回答诸 ...
随机推荐
- STM32之DMA+ADC
借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...
- javascript 创建对象的7种模式
使用字面量方式创建一个 student 对象: var student = function (){ name : "redjoy", age : 21, sex: women, ...
- tomcat之Session的管理
Session是由服务器端的应用服务器容器(如Tomcat.Jetty)存储的.下面分析一下Tomcat是如何管理Session的. 转自:tomcat架构分析 (Session管理) Tomcat中 ...
- android audio无法自动播放
audio无法在android4.4+和ios6以上的版本自动播放,因为他们出于安全考虑,做了限制.必须用户自己手工点击才能播放,程序是控制不了播放的. 整死我了,整整搞了2天,查不出所以然,原来就这 ...
- (转)详解css3弹性盒模型(Flexbox)
今天刚学了css3的弹性盒模型,这是一个可以让你告别浮动.完美实现垂直水平居中的新特性. Flexbox是布局模块,而不是一个简单的属性,它包含父元素和子元素的属性. Flexbox布局的主体思想是似 ...
- php 图片上传的公共方法(按图片宽高缩放或原图)
写的用于图片上传的公共方法类调用方法: $upload_name='pic';$type = 'logo_val';$file_name = 'logo_' . $user_id .create_st ...
- 防御sql注入
1. 领域驱动安全 领域驱动安全是一种代码设计方法.其思想是将一个隐式的概念转化为显示,个人认为即是面向对象的方法,将一个概念抽象成一个类,在该类中通过方法对类的属性进行约束.是否是字符串,包含什么字 ...
- 浅谈Js对象的概念、创建、调用、删除、修改!
一.我们经常困惑,对象究竟是什么,其实这是一种思维,一种意识上的东西,就像我们都说 世界是有物质组成的道理一样,理解了下面的几句话!对象也不是那么抽象! 1.javascript中的所有事 ...
- Microsoft JScript 运行时错误: 属性“$”的值为 null、未定义或不是 Function 对象
运行网站时有的页面中可能有的js代码不起作用,原因可能是 JQ引用错误!他找不到JQ的基类!你引用的是JQ的插件.程序是先找到JQ的基类才能去实现插件功能的.把JQ的基类放在所有插件的前面.这样就不会 ...
- HDFS Client 设计实现解析
前面对 HDFS NameNode 和 DataNode 的架构设计实现要点做了介绍,本文对 HDFS 最后一个主要构成组件 Client 做进一步解析. 流式读取 HDFS Client 为客户端应 ...