前面的话

  文本节点顾名思义指向文本的节点,网页上看到的文字内容都属于文本节点。该节点简单直观,本文将详细介绍该部分内容

特征

  文本节点由Text类型表示,包含的是纯文本内容,但文本节点是对象类型

<div id="box">内容</div>
<script>
console.log(box.firstChild);//"内容"
console.log(typeof box.firstChild);//'object'
</script>

  纯文本内容中的HTML字符会被转义,关于转义字符的详细情况移步至此

<div id="box">&lt;内容&gt;</div>
<script>
console.log(box.firstChild);//"<内容>""
</script>

  文本节点的三个node属性——nodeType、nodeName、nodeValue分别是3、'#text'和节点所包含的文本,其父节点parentNode指向包含该文本节点的元素节点,文本节点没有子节点

  [注意]DOM树中共存在12种节点类型,详细情况移步至此

<div id="box">test</div>
<script>
var oTxt = box.firstChild;
console.log(oTxt.nodeType);//3
console.log(oTxt.nodeValue);//test
console.log(oTxt.nodeName);//'#text'
console.log(oTxt.parentNode);//<div>
console.log(oTxt.childNodes);//[]
</script>

空白文本节点

  关于文本节点,遇到最多的兼容问题是空白文本节点问题。IE8-浏览器不识别空白文本节点,而其他浏览器会识别空白文本节点

<div id="box">
<div>1</div>
</div>
<script>
//标准浏览器输出[text, div, text],text表示空白文本节点
//IE8-浏览器输出[div],并不包含空白文本节点
console.log(box.childNodes);
</script>

属性

data

  文本节点的data属性与nodeValue属性相同

<div id="box">test</div>
<script>
var oBox = document.getElementById('box');
var oTest = oBox.firstChild;
//test test true
console.log(oTest.nodeValue,oTest.data,oTest.data === oTest.nodeValue);
</script>

wholeText

  wholeText属性将当前Text节点与毗邻的Text节点,作为一个整体返回。大多数情况下,wholeText属性的返回值,与data属性和textContent属性相同。但是,某些特殊情况会有差异

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

<div id="test">123</div>
<script>
console.log(test.firstChild.wholeText);//123
console.log(test.firstChild.data);//123
//以索引1为指定位置分割为两个文本节点
test.firstChild.splitText(1);
console.log(test.firstChild.wholeText);//123
console.log(test.firstChild.data);//1
</script>

length

  文本节点的length属性保存着节点字符的数目,而且nodeValue.length、data.length也保存着相同的值

<div id="box">test</div>
<script>
var oBox = document.getElementById('box');
var oTest = oBox.firstChild;
//4 4 4
console.log(oTest.length,oTest.nodeValue.length,oTest.data.length);
</script>

方法

createTextNode()

  createTextNode()方法用于创建文本节点,这个方法接收一个参数——要插入节点中的文本

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = document.createTextNode('<strong>hello</strong> world!');
oBox.appendChild(oText);
//'123&lt;strong&gt;hello&lt;/strong&gt; world!'
console.log(oBox.innerHTML);
//此时,页面中有两个文本节点
console.log(oBox.childNodes.length);
</script>

normalize()

  normalize()方法的作用是合并相邻的文本节点,该方法在文本节点的父节点——元素节点上调用

  [注意]IE9+浏览器无法正常使用该方法

<div id="box">0</div>
<script>
var oText1 = document.createTextNode('1');
var oText2 = document.createTextNode('2');
box.appendChild(oText1);
box.appendChild(oText2);
console.log(box.childNodes);//[text, text, text]
console.log(box.childNodes.length);//3
box.normalize();
//IE9+浏览器返回[text,text],而其他浏览器返回[text]
console.log(box.childNodes);
//IE9+浏览器返回'01',而其他浏览器返回'012'
console.log(box.childNodes[0]);
//IE9+浏览器返回2,使用该方法时只能将所有的文本节点减1;其他浏览器正常,返回2
console.log(box.childNodes.length);//1
</script>

splitText()

  与normalize()方法作用相反,splitText()方法将一个文本节点分成两个文本节点,即按照指定的位置分割nodeValue值。原来的文本节点将包含从开始到指定位置之前的内容。这个方法会返回一个新文本节点,包含剩下的文本。splitText()方法返回的节点与原节点的parentNode相同

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var newNode = oBox.firstChild.splitText(1);
console.log(newNode,newNode === oBox.lastChild);//'23' true
console.log(oBox.firstChild);//'1'
</script>

appendData()

  appendData(text)方法将text添加到节点的末尾,该方法无返回值

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
console.log(oText.appendData('4'));//undefined
console.log(oText.data);//'1234'
console.log(oBox.childNodes.length);//1
</script>

deleteData()

  deleteData(offset,count)方法从offset指定的位置开始删除count个字符,无返回值

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
console.log(oText.deleteData(0,2));//undefined
console.log(oText.data);//'3'
console.log(oBox.childNodes.length);//1
</script>

insertData()

  insertData(offset,text)方法在offset指定的位置插入text,无返回值

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
console.log(oText.insertData(1,'test'));//undefined
console.log(oText.data);//'1test23'
console.log(oBox.childNodes.length);//1
</script>

replaceData()

  replaceData(offset,count,text)方法用text替换从offset指定位置开始到offset+count为止的文本,无返回值

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
console.log(oText.replaceData(1,1,"test"));//undefined
console.log(oText.data);//'1test3'
console.log(oBox.childNodes.length);//1
</script>

substringData()

  substringData(offset,count)方法提取从offset指定的位置开始到offset+count为止处的字符串,并返回该字符串。原来的文本节点无变化

<div class="box" id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
console.log(oText.substringData(1,1));//'2'
console.log(oText);//'123'
</script>

性能

  通过上面的方法介绍,我们会发现,文本节点的操作与字符串的操作方法相当类似。一般地,我们获取文本都用innerHTML,然后再去字符串的操作方法去操作。下面对两者的性能进行对比分析

  【1】首先,对replaceData()和replace()这两个方法进行比较。replace()方法又分为两个方法,一个是在循环中直接对innerHTML进行赋值;另一个是在循环中对变量进行赋值,最后再赋值给innerHTML

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
var str = oBox.innerHTML; function stringTest1(){
for(var i = 0; i < 1000000; i++){
oBox.innerHTML = str.replace(1,Math.floor(Math.random() * 9 + 1));
}
}
var start1 = Date.now();
stringTest1();
var stop1 = Date.now();
result1 = stop1 - start1;
console.log('str1',result1)//2351 /*********************************/
function stringTest2(){
for(var i = 0; i < 1000000; i++){
str.innerHTML = str.replace(1,Math.floor(Math.random() * 9 + 1));
}
}
var start2 = Date.now();
stringTest2();
oBox.innerHTML = str;
var stop2 = Date.now();
result2 = stop2 - start2;
console.log('str2',result2)//408 /*********************************/
function dataTest1(){
for(var i = 0; i < 1000000; i++){
oText.replaceData(1,1,Math.floor(Math.random() * 9 + 1))
}
}
var start3 = Date.now();
dataTest1();
var stop3 = Date.now();
result3 = stop3 - start3;
console.log('data',result3)//327
</script>

  从结果中可以看出,在100万次的循环中,直接操作innerHTML开销较大,操作文本节点的的开销最小

  【2】对substring()和substringData()方法进行比较,这两种方法都用于提取子串

<div id="box">123</div>
<script>
var oBox = document.getElementById('box');
var oText = oBox.firstChild;
var str = oBox.innerHTML; function stringTest(){
for(var i = 0; i < 10000000; i++){
str.substring(Math.floor(Math.random() * 2),2);
}
}
var start = Date.now();
stringTest();
var stop = Date.now();
result = stop - start;
console.log('str',result)//364
/*********************************/
function dataTest(){
for(var i = 0; i < 10000000; i++){
oText.substringData(Math.floor(Math.random() * 2),1);
}
}
var start = Date.now();
dataTest();
var stop = Date.now();
result = stop - start;
console.log('str',result)//1195
</script>

  从结果中可以看出,在1000万次的循环中,使用substringData()方法比substring()方法的开销较大

最后

  元素的文本可以看成字符串,也可以看成节点

  除了字符串操作方法,也可以使用正则或者文本节点方法

  思路广一点,解决问题时才更自如一点

  以上

深入理解DOM节点类型第二篇——文本节点Text的更多相关文章

  1. 深入理解javascript函数系列第二篇——函数参数

    × 目录 [1]arguments [2]内部属性 [3]函数重载[4]参数传递 前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传 ...

  2. 深入理解javascript作用域系列第二篇——词法作用域和动态作用域

    × 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...

  3. 深入理解javascript作用域系列第二篇

    前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作 ...

  4. 深入理解DOM节点类型第一篇——12种DOM节点类型概述

    × 目录 [1]元素 [2]特性 [3]文本[4]CDATA[5]实体引用[6]实体名称[7]处理指令[8]注释[9]文档[10]文档类型[11]文档片段[12]DTD 前面的话 DOM是javasc ...

  5. 深入理解DOM事件类型系列第一篇——鼠标事件

    × 目录 [1]类型 [2]顺序 [3]坐标位置[4]修改键[5]相关元素[6]鼠标按键[7]滚轮事件[8]移动设备 前面的话 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备.本文 ...

  6. 深入理解DOM事件类型系列第三篇——变动事件

    × 目录 [1]删除节点 [2]插入节点 [3]特性节点[4]文本节点 前面的话 变动(mutation)事件能在DOM中的某一部分发生变化时给出提示,这类事件非常有用,但都只能使用DOM2级事件处理 ...

  7. 深入理解javascript对象系列第二篇——属性操作

    × 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...

  8. xpath的数据和节点类型以及XPath中节点匹配的基本方法

    XPath数据类型  XPath可分为四种数据类型:  节点集(node-set)  节点集是通过路径匹配返回的符合条件的一组节点的集合.其它类型的数据不能转换为节点集.  布尔值(boolean)  ...

  9. 深入理解DOM事件类型系列第二篇——键盘事件

    × 目录 [1]类型 [2]顺序 [3]按键信息[4]应用 前面的话 鼠标和键盘是电脑端主要的输入设备,上篇介绍了鼠标事件,本文将详细介绍键盘事件 类型 键盘事件用来描述键盘行为,主要有keydown ...

随机推荐

  1. 怎样两个月完成Udacity Data Analyst Nanodegree

    在迷恋数据科学很久后,我决定要在MOOC网站上拿到一份Data Science的证书.美国三个MOOC网站,Udacity上的课程已经被分成了数个nanodegree,每个nanodegree都是目前 ...

  2. 跟着老男孩教育学Python开发【第二篇】:Python基本数据类型

    运算符 设定:a=10,b=20 . 算数运算 2.比较运算 3.赋值运算 4.逻辑运算 5.成员运算 基本数据类型 1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**3 ...

  3. 智能头盔 "Livall携全球首款智能骑行头盔亮相CES"

    LIVALL是全球首创集音乐.通讯.智能灯光为一体的智能骑行头盔的研发者,日前Livall携旗下智能骑行头盔BH 100和BH 60参展CES 2017,这也是目前世全球首款智能骑行头盔类产品,同时亮 ...

  4. 一步步学习javascript基础篇(8):细说事件

    终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...

  5. 曲演杂坛--蛋疼的ROW_NUMBER函数

    使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...

  6. 压缩javascript文件方法

    写在前面的话:正式部署前端的时候,javascript文件一般需要压缩,并生成相应的sourcemap文件,对于一些小型的项目开发,这里提供一个简单的办法. ======正文开始====== 1.下载 ...

  7. 电容与EMC-电容不同功能时对整板EMC的作用

    一般我们的pcb板的器件有很多种类,但是值得特别关注的,很多人都会说是BGA.接口.IC.晶振之类,因为这些都是layout功能模块以及设计难点.然而数量上占绝对优势的器件却是阻容器件,之前围殴阻抗时 ...

  8. Struts2拦截器的执行过程浅析

    在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...

  9. javaScript语法总结

    一:语法 JavaScript:一种基于对象和事件驱动得客户端脚本语言: 由下面三者组成: 1,ECMAScript(一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer ...

  10. mongoose - 让node.js高效操作mongodb

    Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用. ...