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() 嘿嘿嘿