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 相关文章推荐
JS/jquery实现一个网页内同时调用多个倒计时的方法
Apr 27 jQuery
jQuery Ajax使用FormData上传文件和其他数据后端web.py获取
Jun 11 jQuery
jquery点击回车键实现登录效果并默认焦点的方法
Mar 09 jQuery
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
Mar 28 jQuery
jQuery实现每隔一段时间自动更换样式的方法分析
May 03 jQuery
jQuery实现动态加载select下拉列表项功能示例
May 31 jQuery
详解jQuery中的easyui
Sep 02 jQuery
JQuery实现ajax请求的示例和注意事项
Dec 10 jQuery
jQuery实现的图片点击放大缩小功能案例
Jan 02 jQuery
jQuery 判断元素是否存在然后按需加载内容的实现代码
Jan 16 jQuery
js与jquery获取input输入框中的值实例讲解
Feb 27 jQuery
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
Mar 20 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中Object对象的笔记分享
2011/06/28 PHP
细谈php中SQL注入攻击与XSS攻击
2012/06/10 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
2016/11/10 PHP
php实现xml转换数组的方法示例
2017/02/03 PHP
微信企业转账之入口类分装php代码
2018/10/01 PHP
JQuery 初体验(建议学习jquery)
2009/04/25 Javascript
js读取本地excel文档数据的代码
2010/11/11 Javascript
Jquery命名冲突解决的五种方案分享
2012/03/16 Javascript
妙用Jquery的val()方法
2012/06/27 Javascript
查找iframe里元素的方法可传参
2013/09/11 Javascript
关于JavaScript中name的意义冲突示例介绍
2014/05/29 Javascript
js事件监听机制(事件捕获)总结
2014/08/08 Javascript
JavaScript字符串对象toLowerCase方法入门实例(用于把字母转换为小写)
2014/10/17 Javascript
BootStrap智能表单实战系列(六)表单编辑页面的数据绑定
2016/06/13 Javascript
最全的Javascript编码规范(推荐)
2016/06/22 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
基于BootStrap与jQuery.validate实现表单提交校验功能
2016/12/22 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
2017/06/08 jQuery
基于react组件之间的参数传递(详解)
2017/09/05 Javascript
React-Native使用Mobx实现购物车功能
2017/09/14 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
Vue基于NUXT的SSR详解
2017/10/24 Javascript
深入理解vue-class-component源码阅读
2019/02/18 Javascript
JS实现网站吸顶条
2020/01/08 Javascript
浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器
2019/03/11 Python
django中的图片验证码功能
2019/09/18 Python
python机器学习实现决策树
2019/11/11 Python
美国女性运动零售品牌:Lady Foot Locker
2017/05/12 全球购物
M.M.LaFleur官网:美国职业女装品牌
2020/10/27 全球购物
异常和异常类的概念
2014/09/12 面试题
生物技术毕业生自荐信
2013/10/23 职场文书
干部培训自我鉴定
2014/01/22 职场文书
考核评语大全
2014/04/29 职场文书
高中教师先进事迹材料
2014/08/22 职场文书
钱塘江大潮导游词
2015/02/03 职场文书
《去年的树》教学反思
2016/02/18 职场文书