jQuery中实现text()的方法
嘿嘿嘿
一、有这样一段 html
<div class="divone"> <p>嘿嘿嘿</p> </div> <div class="divone"> <p>哈哈哈</p> </div>
二、jquery 的 text() 方法
(1)当直接调用 $().text()
时,.text()的作用是(循环)读取(多个)目标元素的textcontent/nodevalue
简单实现:
function readtext(elem) { let node, 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) } } //元素节点,文档节点,文档碎片 else if (nodetype === 1 || nodetype === 9 || nodetype === 11) { //如果目标元素的内容是文本,则直接返回 if (typeof elem.textcontent === "string") { /*jquery没有用innertext获取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在ie8中新节点插入会保留所有回车。 所以jquery采用了textcontent获取文本值, textcontent本身是dom3规范的,可以兼容火狐下的innertext问题。*/ return elem.textcontent } //如果节点内容不是文本,则循环子节点,并依次获取它们的文本节点 else { for (elem = elem.firstchild; elem; elem = elem.nextsibling) { ret += readtext(elem) } } } //文本节点、一个文档的cdata部分(没遇到过这个) else if (nodetype === 3 || nodetype === 4) { //返回节点值 return elem.nodevalue; } //nodetype:注释节点 8,处理指令 7 //text()方法不处理这两个类型节点 return ret }
(2)当调用$().text(value)
时,.text(value)的作用是为每一个符合条件的目标元素的textcontent设置为 value
简单实现:
writetext():
function writetext(value) { let elem, 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; } } //return this 方便链式调用 return this }
customempty():
function customempty() { let elem, i = 0; //注意for循环的写法 for (; (elem = this[i]) != null; i++) { //如果是元素节点的话,清空该节点的所有内容 if (elem.nodetype === 1) { elem.textcontent = ""; } } return this; }
(3)源码实现
源码:
jquery.text()总体:
//源码6152行 text: function( value ) { return access( this, function( value ) { return value === 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 ) { var node, ret = "", i = 0, nodetype = elem.nodetype; if ( !nodetype ) { while ( (node = elem[i++]) ) { // do not traverse comment nodes ret += gettext( node ); } } //元素节点、文档节点、文档碎片 else if ( nodetype === 1 || nodetype === 9 || nodetype === 11 ) { // use textcontent for elements // innertext usage removed for consistency of new lines (jquery #11153) //如果目标元素的子节点是文本节点,则直接返回它的textcontent if ( typeof elem.textcontent === "string" ) { /*jquery没有用innertext获取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在ie8中新节点插入会保留所有回车。 所以jquery采用了textcontent获取文本值, textcontent本身是dom3规范的,可以兼容火狐下的innertext问题。*/ return elem.textcontent; } //如果子节点不是文本节点,则循环子节点,并依次获取它们的文本节点 else { // traverse its children for ( elem = elem.firstchild; elem; elem = elem.nextsibling ) { ret += gettext( elem ); } } } //文本节点、一个文档的cdata部分(没遇到过这个) else if ( nodetype === 3 || nodetype === 4 ) { return elem.nodevalue; } // do not include comment or processing instruction nodes return ret; };
③ .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() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { //如果是元素节点的话 if ( elem.nodetype === 1 ) { // prevent memory leaks //清空内容和事件,防止内存泄漏 jquery.cleandata( getall( elem, false ) ); // remove any remaining nodes //清空节点所有内容 elem.textcontent = ""; } } return this; },
④ 总结
$(".divone").text()
的本质:
(1)节点内容是文本,返回$(".divone")[i].textcontent
(2)节点内容不是文本,循环返回$(".divone")[i].element[j].textcontent
(3)节点内容是文本节点或一个文档的cdata部分,则返回$(".divone")[i]. nodevalue
$(".divone").text("hello <b>world</b>!")
的本质:
(1)jquery.cleandata()
(2)$(".divone")[i].textcontent = ""
(3)$(".divone")[i].textcontent="hello world!"
注意:text() 不会去解析 html 标签!
参考:
完整代码:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jquery之text()</title> </head> <body> <script src="jquery.js"></script> <div class="divone"> <!--<p id="divtwo">嘿嘿嘿</p>--> <p>嘿嘿嘿</p> </div> <div class="divone"> <p>哈哈哈</p> </div> <input type="text" id="inputone"> <script> function readtext(elem) { let node, 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) } } //元素节点,文档节点,文档碎片 else if (nodetype === 1 || nodetype === 9 || nodetype === 11) { //如果目标元素的内容是文本,则直接返回 if (typeof elem.textcontent === "string") { /*jquery没有用innertext获取文本的值,http://bugs.jquery.com/ticket/11153, 大概就是在ie8中新节点插入会保留所有回车。 所以jquery采用了textcontent获取文本值, textcontent本身是dom3规范的,可以兼容火狐下的innertext问题。*/ return elem.textcontent } //如果节点的内容不是文本,则循环子节点,并依次获取它们的文本节点 else { for (elem = elem.firstchild; elem; elem = elem.nextsibling) { ret += readtext(elem) } } } //文本节点、一个文档的cdata部分(没遇到过这个) else if (nodetype === 3 || nodetype === 4) { //返回节点值 return elem.nodevalue; } //nodetype:注释节点 8,处理指令 7 //text()方法不处理这两个类型节点 return ret } function customempty() { let elem, i = 0; //注意for循环的写法 for (; (elem = this[i]) != null; i++) { //如果是元素节点的话,清空该节点的所有内容 if (elem.nodetype === 1) { elem.textcontent = ""; } } return this; } function writetext(value) { let elem, 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; } } //return this 方便链式调用 return this } function customtext(value) { return value === undefined ? //读 readtext(this) : //写 writetext.call(this, value) } customtext.call(document.queryselectorall('.divone')) customtext.call(document.queryselectorall('.divone'),"hello <b>world</b>!") // let p=document.createelement('p') // p.innertext='哈哈哈' console.log($(".divone").text()) // customtext.call(document.queryselectorall('.divone')) // console.log(document.queryselectorall('.divone').nodetype,'childnode81') // console.log(document.queryselectorall('.divone')[0].textcontent,'childnode81') // $("#divone").text('<p>aaaa</p>') // console.log(document.queryselector("#divtwo")) </script> </body> </html>
总结
以上所述是小编给大家介绍的jquery中实现text()的方法,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
下一篇: 北魏是怎么分裂的?北魏分裂的原因有哪些?