jQuery中实现text()的方法
一、有这样一段html
嘿嘿嘿
哈哈哈
二、jQuery的text()方法
(1)当直接调用$().text()时,.text()的作用是(循环)读取(多个)目标元素的textContent/nodeValue
简单实现:
functionreadText(elem){
letnode,
ret="",
i=0,
nodeType=elem.nodeType
console.log(nodeType,'nodeType22')
//如果selector是类的话,会有多个目标元素,此时需要分别单个循环
//比如document.querySelectorAll('.divOne').nodeType->undefined
if(!nodeType){
while((node=elem[i++])){
//单个获取
ret+=readText(node)
}
}
//元素节点,文档节点,文档碎片
elseif(nodeType===1||nodeType===9||nodeType===11){
//如果目标元素的内容是文本,则直接返回
if(typeofelem.textContent==="string"){
/*jQuery没有用innerText获取文本的值,http://bugs.jquery.com/ticket/11153,
大概就是在IE8中新节点插入会保留所有回车。
所以jQuery采用了textContent获取文本值,
textContent本身是dom3规范的,可以兼容火狐下的innerText问题。*/
returnelem.textContent
}
//如果节点内容不是文本,则循环子节点,并依次获取它们的文本节点
else{
for(elem=elem.firstChild;elem;elem=elem.nextSibling){
ret+=readText(elem)
}
}
}
//文本节点、一个文档的CDATA部分(没遇到过这个)
elseif(nodeType===3||nodeType===4){
//返回节点值
returnelem.nodeValue;
}
//nodeType:注释节点8,处理指令7
//text()方法不处理这两个类型节点
returnret
}
(2)当调用$().text(value)时,.text(value)的作用是为每一个符合条件的目标元素的textContent设置为value
简单实现:
writeText():
functionwriteText(value){
letelem,
i=0;
//先清空目标元素的内容
customEmpty.call(this)
//循环
for(;(elem=this[i])!=null;i++){
//元素节点,文档碎片,文档节点
if(elem.nodeType===1||elem.nodeType===11||elem.nodeType===9){
//text()方法不会解析标签
elem.textContent=value;
}
}
//returnthis方便链式调用
returnthis
}
customEmpty():
functioncustomEmpty(){
letelem,
i=0;
//注意for循环的写法
for(;(elem=this[i])!=null;i++){
//如果是元素节点的话,清空该节点的所有内容
if(elem.nodeType===1){
elem.textContent="";
}
}
returnthis;
}
(3)源码实现
源码:
jQuery.text()总体:
//源码6152行
text:function(value){
returnaccess(this,function(value){
returnvalue===undefined?
//读
//如果直接调用text()的话,就调用Sizzle.getText
jQuery.text(this):
//写
//循环
this.empty().each(function(){
//先清空目标元素的内容,然后再赋值
if(this.nodeType===1||this.nodeType===11||this.nodeType===9){
console.log(value,'value6159')
//如果包含标签的话,需要用html()方法,text()方法不会解析标签
/*jQuery没有用innerText获取文本的值,http://bugs.jquery.com/ticket/11153,
大概就是在IE8中新节点插入会保留所有回车。
所以jQuery采用了textContent获取文本值,
textContent本身是dom3规范的,可以兼容火狐下的innerText问题。*/
this.textContent=value;
}
})
},null,value,arguments.length);
},
源码解析:
①调用text(),实际上是调用access()
也就是说:调用jQuery.access()相当于调用了fn.call(elems,value),即自定义的方法jQuery.access(this,function(value){xxx})
②.text()的情况调用这部分源码:
jQuery.text()调用的其实是Sizzle.getText():
//源码2833行
jQuery.text=Sizzle.getText;
Sizzle.getText():
//源码1642行
getText=Sizzle.getText=function(elem){
varnode,
ret="",
i=0,
nodeType=elem.nodeType;
if(!nodeType){
while((node=elem[i++])){
//Donottraversecommentnodes
ret+=getText(node);
}
}
//元素节点、文档节点、文档碎片
elseif(nodeType===1||nodeType===9||nodeType===11){
//UsetextContentforelements
//innerTextusageremovedforconsistencyofnewlines(jQuery#11153)
//如果目标元素的子节点是文本节点,则直接返回它的textContent
if(typeofelem.textContent==="string"){
/*jQuery没有用innerText获取文本的值,http://bugs.jquery.com/ticket/11153,
大概就是在IE8中新节点插入会保留所有回车。
所以jQuery采用了textContent获取文本值,
textContent本身是dom3规范的,可以兼容火狐下的innerText问题。*/
returnelem.textContent;
}
//如果子节点不是文本节点,则循环子节点,并依次获取它们的文本节点
else{
//Traverseitschildren
for(elem=elem.firstChild;elem;elem=elem.nextSibling){
ret+=getText(elem);
}
}
}
//文本节点、一个文档的CDATA部分(没遇到过这个)
elseif(nodeType===3||nodeType===4){
returnelem.nodeValue;
}
//Donotincludecommentorprocessinginstructionnodes
returnret;
};
③.text(value)的情况调用这部分源码:
jQuery.text(value):
//写
//循环
this.empty().each(function(){
//先清空目标元素的内容,然后再赋值
if(this.nodeType===1||this.nodeType===11||this.nodeType===9){
console.log(value,'value6159')
//如果包含标签的话,需要用html()方法,text()方法不会解析标签
/*jQuery没有用innerText获取文本的值,http://bugs.jquery.com/ticket/11153,
大概就是在IE8中新节点插入会保留所有回车。
所以jQuery采用了textContent获取文本值,
textContent本身是dom3规范的,可以兼容火狐下的innerText问题。*/
this.textContent=value;
}
})
empty():
//源码6231行
empty:function(){
varelem,
i=0;
for(;(elem=this[i])!=null;i++){
//如果是元素节点的话
if(elem.nodeType===1){
//Preventmemoryleaks
//清空内容和事件,防止内存泄漏
jQuery.cleanData(getAll(elem,false));
//Removeanyremainingnodes
//清空节点所有内容
elem.textContent="";
}
}
returnthis;
},
④总结
$(".divOne").text()的本质:
(1)节点内容是文本,返回$(".divOne")[i].textContent
(2)节点内容不是文本,循环返回$(".divOne")[i].element[j].textContent
(3)节点内容是文本节点或一个文档的CDATA部分,则返回$(".divOne")[i].nodeValue
$(".divOne").text("Helloworld!")的本质:
(1)jQuery.cleanData()
(2)$(".divOne")[i].textContent=""
(3)$(".divOne")[i].textContent="Helloworld!"
注意:text()不会去解析html标签!
参考:http://api.jquery.com/text/
完整代码:
jQuery之text() 嘿嘿嘿