jQuery中实现text()的方法


Posted in jQuery onApril 04, 2019

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

jQuery 相关文章推荐
jQuery插件Echarts实现的渐变色柱状图
Mar 23 jQuery
jQuery实现简单的抽奖游戏
May 05 jQuery
jquery处理checkbox(复选框)是否被选中实例代码
Jun 12 jQuery
浅谈事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流
Jul 22 jQuery
jquery学习笔记之无new构建详解
Dec 07 jQuery
CSS3结合jQuery实现动画效果及回调函数的实例
Dec 27 jQuery
jQuery实现动态显示select下拉列表数据的方法
Feb 05 jQuery
jQuery实现的淡入淡出图片轮播效果示例
Aug 29 jQuery
jQuery事件多次绑定与解绑问题实例分析
Feb 19 jQuery
jquery插件开发模式实例详解
Jul 20 jQuery
JQuery发送ajax请求时中文乱码问题解决
Nov 14 jQuery
jQuery 判断元素是否存在然后按需加载内容的实现代码
Jan 16 jQuery
基于 jQuery 实现键盘事件监听控件
Apr 04 #jQuery
jQuery分组选择器简单用法示例
Apr 04 #jQuery
jQuery实现带3D切割效果的轮播图功能示例【附源码下载】
Apr 04 #jQuery
jquery简单实现纵向的无缝滚动代码实例
Apr 01 #jQuery
jQuery事件blur()方法的使用实例讲解
Mar 30 #jQuery
jQuery实现动态添加和删除input框代码实例
Mar 29 #jQuery
jQuery ajax仿Google自动提示SearchSuggess功能示例
Mar 28 #jQuery
You might like
一个可查询所有表的“通用”查询分页类
2006/10/09 PHP
php下几个常用的去空、分组、调试数组函数
2009/02/22 PHP
PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
2012/04/09 PHP
基于php权限分配的实现代码
2013/04/28 PHP
学习php设计模式 php实现装饰器模式(decorator)
2015/12/07 PHP
Yii使用DeleteAll连表删除出现报错问题的解决方法
2016/07/14 PHP
解决Laravel5.2 Auth认证退出失效的问题
2019/10/14 PHP
JQueryEasyUI datagrid框架的进阶使用
2013/04/08 Javascript
js 判断文件类型并控制表单提交示例代码
2013/11/14 Javascript
深入理解JavaScript中的传值与传引用
2013/12/09 Javascript
JS 实现列表与多选框选择附预览动画
2014/10/29 Javascript
js中split和replace的用法实例
2015/02/28 Javascript
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
Spring Boot+AngularJS+BootStrap实现进度条示例代码
2017/03/02 Javascript
详解angularJS自定义指令间的相互交互
2017/07/05 Javascript
基于jquery的on和click的区别详解
2018/01/15 jQuery
webpack4.0 入门实践教程
2018/10/08 Javascript
jQuery模仿ToDoList实现简单的待办事项列表
2019/12/30 jQuery
js实现表格单列按字母排序
2020/08/12 Javascript
[01:10:30]DOTA2-DPC中国联赛正赛 Dragon vs Dynasty BO3 第一场 3月4日
2021/03/11 DOTA
python3访问sina首页中文的处理方法
2014/02/24 Python
Python win32com 操作Exce的l简单方法(必看)
2017/05/25 Python
Python查找两个有序列表中位数的方法【基于归并算法】
2018/04/20 Python
解决pandas无法在pycharm中使用plot()方法显示图像的问题
2018/05/24 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
2018/09/04 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
python 实现turtle画图并导出图片格式的文件
2019/12/07 Python
python 实现两个npy档案合并
2020/07/01 Python
解决pip install psycopg2出错问题
2020/07/09 Python
Pycharm自动添加文件头注释和函数注释参数的方法
2020/10/23 Python
英国电器零售商:PRC Direct
2018/06/21 全球购物
十八大感想感言
2014/02/10 职场文书
数控专业毕业生求职信
2014/06/12 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
windows安装python超详细图文教程
2021/05/21 Python
Android Canvas绘制文字横纵向对齐
2022/06/05 Java/Android