一、前言                              

由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它(修正:FF45+已经支持innerText属性),一般情况下我们可以使用textContent来代替,但它两者是否就能完全等同呢?在坑爹的表单元素(如input、textarea等)中表现是否依旧诡异呢?文本将记录一些实验结果,避免日后被玩坏。

二、innerHTML                          

由于innerText和textContent均为对innerHTML内容作不同的处理而成,因此我们需要先明确innerHTML属性的特点。

赋值操作:先对值内容进行模式匹配,然后把处理后的值赋予给innerHTML属性。

模式匹配结果将导致 保留将字符转换为HTML实体 两个操作。

a). 以下情况将被保留

1. HTML实体(ASCII实体、符号实体和字符实体)的实体名或实体编号;

2. 符号实体和字符实体对应的字符;

3. 没有HTML实体与之对应的字符;

4. HTML标签。(如<img>)

b). 以下情况将会执行字符转换为HTML实体

1. ASCII实体对应的字符(<、>、&、'和")。

也就是说除了单独的 <、>、&、'和" 会被转换为实体名外,将原封不动地将值赋予给innerHTML属性。

取值操作:直接获取innerHTML属性值。

后面的innerText和textContent内容将以下面的HTML Markup作为实验原材料

<style type="text/css">
.line3, .line4{
float: left;
}
.line5::after{
content: "test"
}
</style>
<div id="view">
<div>line1</div>
<div>line2</div><br/>
<div class="line3">line3</div>
<div class="line4">line4</div>
<div style="clear:both;"></div>
<div class="line5">line5</div>
</div>
<script type="text/javascript">
var view = document.getElementById('view')
</script>

二、innerText                         

浏览器支持:IE、Chrome

赋值操作:先将ASCII实体对应的字符(<、>、&、'和")转换为实体名,然后把处理后的值赋予给innerHTML属性。

取值操作:innerText的取值实际上就是对innerHTML的属性值进行一系列处理,然后返回,具体步骤如下

1. 对HTML标签进行解析;

2. 对CSS样式进行带限制的解析和渲染;

3. 将ASCII实体转换为对应的字符;

4. 剔除格式信息(如\t、\r和\n等),将多个连续的空格合并为一个。

IE各版本和Chrome下对innerText进行取值均执行上述4步,但效果不尽相同。实验结果如下:

  IE5.5~8

页面显示效果:

line1
line2 line3line4
line5

innerText取值结果:

"line1
line2 line3line4line5"

不全面的小结:在进行CSS样式渲染时,不支持伪元素和clear:both。

  IE9~11

页面显示效果:

line1
line2 line3line4
line5test

innerText取值结果:

"line1

line2

line3

line4

line5"

不全面的小结:在进行CSS样式渲染时,只会应用元素的默认样式。

Chrome

页面显示效果:

line1
line2 line3line4
line5test

innerText取值结果:

"line1
line2 line3line4
line5"

不全面的小结:在进行CSS样式渲染时,不支持伪元素。

三、textContent                        

  浏览器支持:IE9~11、FireForx、Chrome

赋值操作:先将ASCII实体对应的字符(<、>、&、'和")转换为实体名,然后把处理后的值赋予给innerHTML属性。

取值操作:textContent的取值实际上就是对innerHTML的属性值进行一系列处理,然后返回,具体步骤如下

1. 对HTML标签进行剔除;

2. 将ASCII实体转换为相应的字符。

注意:

a). 对HTML标签是剔除不是解析,也不会出现CSS解析和渲染的处理,因此<br/>等元素是不生效的。

b). 不会剔除格式信息和合并连续的空格,因此\t、\r、\n和连续的空格将生效。

所有浏览器效果统一,界面效果:

line1
line2 line3line4
line5test

textContent取值结果:

"
line1
line2
line3
line4 line5
"

四、表单元素中的innerHTML、innerText、textContent和value  

到这里大家应该对innerHTML、innerText和textContent之间的关系和行为有一定了解了,但不幸的是表单元素一如既往地会推翻我们之前的理解。请注意的是上述的关系和行为仅限于非表单元素,而本节将介绍表单元素textarea和input[type="text"]相关的蛋疼……

前置信息: textarea和input[type="text"]的value属性与界面输入框是对应的,通过value属性赋值与在界面输入框输入值属于同一个操作。

  textarea

FireFox

a). innerHTML可被设置并且生效,对其他属性的影响:

1. 无条件影响textContent的取值;

2. 在通过value属性赋值前,会影响value的取值;

3. 在通过value属性赋值后,则value的取值与innerHTML无关。

b). textContent可被设置且生效,对其他属性的影响:

     1. 无条件影响innerHTML的取值;

    2. 在通过value属性赋值前,会影响value的取值;

3. 在通过value属性赋值后,则value的取值与textContent无关。

c). value可被设置且生效。

Chrome

   a). innerHTML可被设置并且生效,对其他属性的影响:

1. 无条件影响innerText、textContent的取值;

2. 在通过value属性赋值前,会影响value的取值;

3. 在通过value属性赋值后,则value的取值与innerHTML无关。

   b). innerText可被设置并且生效,对其他属性的影响:

1. 无条件影响innerHTML、textContent的取值;

2. 在通过value属性赋值前,会影响value的取值;

3. 在通过value属性赋值后,则value的取值与innerText无关。

c). textContent可被设置且生效,对其他属性的影响:

     1. 无条件影响innerHTML、innerText的取值;

    2. 在通过value属性赋值前,会影响value的取值;

3. 在通过value属性赋值后,则value的取值与textContent无关。

d). value可被设置且生效。

    IE9~11

  innerHTML、value、innerText和textContent均可设置且有效,无条件相互影响取值。

    IE5.5~8

innerHTML、value、innerText和textContent均可设置且有效,无条件相互影响取值。

  input[type="text"]

    FireFox

  a). innerHTML可被设置且生效,无条件影响innerText和textContent的取值,但不会影响value的取值。

b). textContent可被设置且生效,无条件影响innerHTML的取值,但不会影响value的取值。

  c). value可被设置且生效,不会影响innerHTML和textContent的取值。

Chrome   

  a). innerHTML可被设置但无效,属性值永远保持空字符串。

  b). textContent可被设置且生效,但不会影响value、innerHTML和innerText的取值。

  c). innerText可被设置,但实际设置时会抛异常

<input type="text" id="target">
<script type="text/javascript">
var getDesc = function(){ return Object.getOwnPropertyDescriptor.apply(Object, arguments) }
, get = function(){ return document.getElementById.apply(docuemnt, arguments) }
var target = get('target');
console.log(getDesc(target, 'innerText')) // Object {value: "", writable: true, enumerable: true, configurable: true}
target.innerText = "" // NoModificationAllowedError: Failed to set the 'innerText' property on 'HTMLElement': The 'input' element does not support text insertion.
</scr

  d). value可被设置且生效,但不会影响textContent、innerHTML和innerText的取值。

   IE5.5~8

a). innerHTML可被设置,但实际设置时会抛异常

<input type="text" id="target">
<script type="text/javascript">
var getDesc = function(){ return Object.getOwnPropertyDescriptor.apply(Object, arguments) }
, get = function(){ return document.getElementById.apply(docuemnt, arguments) }
var target = get('target');
console.log(getDesc(target, 'innerHTML')) // Object {value: "", writable: true, enumerable: true, configurable: true}
target.innerText = "" // 未知的运行时错误
</script>

b). innerText可被设置且有效,无条件影响value取值。但innerText的取值永远是空字符串。

c). value可被设置且生效,但不会影响innerHTML和innerText的取值。

 IE9~11

   a). innerHTML可被设置且生效,无条件影响innerText和textContent的取值。但不影响value的取值。

b). innerText可被设置且生效,无条件影响value取值。但不影响innerHTML和textContent。innerText的取值由innerHTML的属性值经过处理后返回。

// 假设a是input[type="text"]
a.innerHTML = "<"
a.innerText = "test"
console.log(a.innerHTML) // &lt;
console.log(a.value) // test
console.log(a.innerHTML) // <

c). textContent可被设置且生效,无条件影响innerHTML和innerText的取值,textContent的取值由innerHTML的属性值经过处理后返回。

d). value可被设置且生效,但不会影响innerHTML、textContent和innerText的取值。

五、HTML编码                         

所谓HTML编码其实就是将字符转换为HTML实体,这是防止脚本注入的重要手段之一。

由于表单元素的value与innerHTML关系在不同浏览器上表现各不相同,因此最保险的方式还是

;(function(exports, doc){
var dom = doc.createElement('textarea') exports.encode = function(raw){
dom.innerHTML = raw
return dom.innerHTML
}
exports.decode = function(str){
dom.innerHTML = str
return dom['innerText' in dom ? 'innerText' : 'textContent']
}
}(window.htmlEncoder = {}, document))

六、总结                            

本文若有纰漏请大家指正补充,谢谢!

尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4319635.html ^_^肥仔John

JS魔法堂:被玩坏的innerHTML、innerText、textContent和value属性的更多相关文章

  1. JS魔法堂:浏览器模式和文档模式怎么玩?

    一.前言 从IE8开始引入了文档兼容模式的概念,作为开发人员的我们可以在开发人员工具中通过“浏览器模式”和“文档模式”(IE11开始改为“浏览器模式”改成更贴切的“用户代理字符串”)品味一番,它的出现 ...

  2. JS魔法堂:不完全国际化&本地化手册 之 理論篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  3. JS魔法堂:不完全国际化&本地化手册 之 实战篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  4. JS魔法堂:LINK元素深入详解

    一.前言 我们一般使用方式为 <link type="text/css" rel="stylesheet" href="text.css&quo ...

  5. JS魔法堂:doctype我们应该了解的基础知识

    一.前言 什么是doctype?其实我们一直使用,却很少停下来看清楚它到底是什么,对网页有什么作用.本篇将和大家一起探讨那个默默无闻的doctype吧! 二.什么是doctype doctype或DT ...

  6. JS魔法堂:精确判断IE的文档模式by特征嗅探

    一.前言 苦逼的前端攻城狮都深受浏览器兼容之苦,再完成每一项功能前都要左顾右盼,生怕浏览器不支持某个API,生怕原生API内含臭虫因此判断浏览器类型和版本号成了不可绕过的一道关卡,而特征嗅探是继浏览器 ...

  7. JS魔法堂:追忆那些原始的选择器

    一.前言                                                                                                 ...

  8. JS魔法堂:判断节点位置关系

    一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...

  9. JS魔法堂:IMG元素加载行为详解

    一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...

  10. JS魔法堂:jsDeferred源码剖析

    一.前言 最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地参考了由日本geek cho45发起的jsDeferred项目(<JavaScript框架设计& ...

随机推荐

  1. Apache Marmotta 3.1.0-incubating 发布

    Apache Marmotta 3.1.0-incubating 发布了,Apache Marmotta 项目的目的是提供 Linked Data Platform 的开源实现,可让组织轻松的使用.扩 ...

  2. Oracle常见授权与回收权限(grant和revoke)学习记录

      1.GRANT 赋于权限常用的系统权限集合有以下三个:CONNECT(基本的连接), RESOURCE(程序开发), DBA(数据库管理) 常用的数据对象权限有以下五个:ALL ON 数据对象名, ...

  3. RCP: JDT 根据org.eclipse.jdt.core.IJavaElement对象获取org.eclipse.jdt.core.dom.ASTNode对象

    JDT中有两套Java文件模型映射. 其核心类\接口分别为: org.eclipse.jdt.core.IJavaElement和org.eclipse.jdt.core.dom.ASTNode IJ ...

  4. python sorted排序

    python sorted排序 Python不仅提供了list.sort()方法来实现列表的排序,而且提供了内建sorted()函数来实现对复杂列表的排序以及按照字典的key和value进行排序. s ...

  5. VS2013 好用的插件

    切换到vs2013上有些时间了,以下是我个人认为比较好的插件. Resharper 神器中的神器,提升编码效率的第一神器,附带提高编码能力:除去臃肿的体积,堪称完美: Productivity Pow ...

  6. MVVM架构~knockoutjs系列之验证信息自定义输出~续

    返回目录 上一讲中,我以一个实际中的例子说明了knockoutjs的自定义验证功能,在使用过程中,出现了一个问题,当然了不是问题,只是一种需求,上一讲中自定义验证的表现是:当页面加载后,自动显示有问题 ...

  7. lua的私有性(privacy)

    很多人认为私有性是面向对象语言的应有的一部分.每个对象的状态应该是这个对象自己的事情.在一些面向对象的语言中,比如C++和Java你可以控制对象成员变量或者成员方法是否私有.其他一些语言比如Small ...

  8. fir.im Weekly - iOS 保持界面流畅的技巧

    生命不息,coding 不止.本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码分享,产品 UI 设计的好文章,还有一些程序员成长的 Tips,希望 ...

  9. SQL SERVER 查询性能优化——分析事务与锁(五)

    SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...

  10. Python数组合并

    Python数组合并 a = [1, 2] b = [3, 4] c = a + b print(c) # [1, 2, 3, 4]