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实现动态添加、删除按钮及input输入框的方法
Apr 27 jQuery
jQuery实现jQuery-form.js实现异步上传文件
Apr 28 jQuery
zTree jQuery 树插件的使用(实例讲解)
Sep 25 jQuery
jQuery实现鼠标点击处心形漂浮的炫酷效果示例
Apr 12 jQuery
如何用input标签和jquery实现多图片的上传和回显功能
May 16 jQuery
jQuery 导航自动跟随滚动的实现代码
May 30 jQuery
jQuery实现参数自定义的文字跑马灯效果
Aug 15 jQuery
jQuery md5加密插件jQuery.md5.js用法示例
Aug 24 jQuery
基于jQuery ztree实现表格风格的树状结构
Aug 31 jQuery
js/jQuery实现全选效果
Jun 17 jQuery
jQuery实现简单聊天室
Feb 08 jQuery
jQuery实现移动端扭蛋机抽奖
Nov 08 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
php切割页面div内容的实现代码分享
2012/07/31 PHP
php ImageMagick windows下安装教程
2015/01/26 PHP
php版微信小店API二次开发及使用示例
2016/11/12 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
Laravel配置全局公共函数的方法步骤
2019/05/09 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
2020/02/21 PHP
laravel admin实现分类树/模型树的示例代码
2020/06/10 PHP
srcElement表格样式
2006/09/03 Javascript
扩展String功能方法
2006/09/22 Javascript
jquery select下拉框操作的一些说明
2010/04/02 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
2014/03/28 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
js和jquery分别验证单选框、复选框、下拉框
2015/12/17 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
vue cli 全面解析
2018/02/28 Javascript
解决使用bootstrap的dropdown部件时报错:error:Bootstrap dropdown require Popper.js问题
2018/08/30 Javascript
vue 解决数组赋值无法渲染在页面的问题
2019/10/28 Javascript
js+css实现全屏侧边栏
2020/06/16 Javascript
Bootstrap FileInput实现图片上传功能
2021/01/28 Javascript
[50:54]完美世界DOTA2联赛 GXR vs IO 第三场 11.07
2020/11/10 DOTA
Python中实现对Timestamp和Datetime及UTC时间之间的转换
2015/04/08 Python
python微信公众号开发简单流程
2018/03/23 Python
python提取图像的名字*.jpg到txt文本的方法
2018/05/10 Python
Django unittest 设置跳过某些case的方法
2018/12/26 Python
Python中Numpy mat的使用详解
2019/05/24 Python
Python求正态分布曲线下面积实例
2019/11/20 Python
keras 实现轻量级网络ShuffleNet教程
2020/06/19 Python
Goodee官方商店:迷你投影仪
2021/03/15 全球购物
酒店副总岗位职责
2013/12/24 职场文书
党的群众路线教育实践活动对照检查材料
2014/09/22 职场文书
乡镇民主生活会发言材料
2014/10/20 职场文书
党建工作汇报材料
2014/12/24 职场文书
物业保安辞职信
2015/05/12 职场文书
航班延误投诉信
2015/07/02 职场文书
乡镇团代会开幕词
2016/03/04 职场文书