首页 > 编程 > JavaScript > 正文

jQuery中实现text()的方法

2019-11-19 11:52:37
字体:
来源:转载
供稿:网友

一、有这样一段 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 标签!

参考:http://api.jquery.com/text/

完整代码:

<!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()的方法,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表