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 dataTable 获取某行数据
May 05 jQuery
jQuery插件开发发送短信倒计时功能代码
May 09 jQuery
JQuery Ajax 异步操作之动态添加节点功能
May 24 jQuery
jQuery中过滤器的基本用法示例
Oct 11 jQuery
jQuery实现的下雪动画效果示例【附源码下载】
Feb 02 jQuery
jQuery 防止相同的事件快速重复触发方法
Feb 08 jQuery
jQuery中元素选择器(element)简单用法示例
May 14 jQuery
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
Jun 05 jQuery
使用jQuery动态设置单选框的选中效果
Dec 06 jQuery
简单易扩展可控性强的Jquery转盘抽奖程序
Mar 16 jQuery
jquery+php后台实现省市区联动功能示例
May 23 jQuery
如何使用Jquery动态生成二级选项列表
Feb 06 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
一个简单的MySQL数据浏览器
2006/10/09 PHP
php获取通过http协议post提交过来xml数据及解析xml
2012/12/16 PHP
php计算给定时间之前的函数用法实例
2015/04/03 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
PHP进程通信基础之信号量与共享内存通信
2017/02/19 PHP
JavaScript CSS菜单功能 改进版
2008/12/20 Javascript
基于JQuery的6个Tab选项卡插件
2010/09/03 Javascript
JQuery设置文本框和密码框得到焦点时的样式
2013/08/30 Javascript
查找iframe里元素的方法可传参
2013/09/11 Javascript
javascript中caller和callee详解
2015/08/10 Javascript
简单的JS时钟实例讲解
2016/01/13 Javascript
Jquery根据浏览器窗口改变调整大小的方法
2017/02/07 Javascript
jQuery+PHP实现上传裁剪图片
2020/06/29 jQuery
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
layui数据表格重载实现往后台传参
2019/11/15 Javascript
微信小程序缓存支持二次开发封装实现解析
2019/12/16 Javascript
js实现文字头像的生成代码
2020/03/07 Javascript
JavaScript检测浏览器是否支持CSS变量代码实例
2020/04/03 Javascript
vue集成openlayers加载geojson并实现点击弹窗教程
2020/09/24 Javascript
决策树剪枝算法的python实现方法详解
2019/09/18 Python
python图像处理模块Pillow的学习详解
2019/10/09 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
python画环形图的方法
2020/03/25 Python
利用Python优雅的登录校园网
2020/10/21 Python
KIKO美国官网:意大利的平价彩妆品牌
2017/05/16 全球购物
什么是Linux虚拟文件系统VFS
2015/08/25 面试题
师范学院教师自荐书
2014/01/31 职场文书
高级销售求职信
2014/02/21 职场文书
桥梁工程专业求职信
2014/04/21 职场文书
中班上学期幼儿评语
2014/04/30 职场文书
股东授权委托书范文
2014/09/13 职场文书
机关干部四风问题自我剖析及整改措施
2014/10/26 职场文书
上班旷工检讨书
2015/08/15 职场文书
Python使用UDP实现720p视频传输的操作
2021/04/24 Python
深入讲解Vue中父子组件通信与事件触发
2022/03/22 Vue.js