当前位置: 移动技术网 > IT编程>开发语言>JavaScript > jQuery中实现text()的方法

jQuery中实现text()的方法

2019年07月24日  | 移动技术网IT编程  | 我要评论

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网