详解jQuery中的getAll()和cleanData()


Posted in jQuery onApril 15, 2019

前言:

看 jQuery 源码的一个痛点就是调用一个函数时,里面会调用 N 个其他函数,然后这 N 个函数里面又会调用 M 个其他其他函数。。

本篇文章主要是对detach()/empty()/remove()/unwrap()]() 中两个函数 getAll和cleanData() 进行解析。

一、getAll(context, tag)

作用:

用来获取 context 上的 tag 标签,或者是将 context 和 context 里的 tag 标签的元素合并

源码:

//一般是传的node,'script'
 //应该是用来获取context上的tag标签,或者是将context和context里的tag标签的元素合并
 //源码4893行
 function getAll( context, tag ) {
  // Support: IE <=9 - 11 only
  // Use typeof to avoid zero-argument method invocation on host objects (#15151)
  var ret;
  console.log(context,typeof context.getElementsByTagName,typeof context.querySelectorAll,'context4894')
  //如果context存在getElementsByTagName的方法的话
  if ( typeof context.getElementsByTagName !== "undefined" ) {
   //tag:script
   //从context中获取script标签的节点
   ret = context.getElementsByTagName( tag || "*" )
   console.log(tag,ret,'ret4897')
  }
 //DocumentFragment没有getElementsByTagName方法,但有querySelectorAll方法
 else if ( typeof context.querySelectorAll !== "undefined" ) {
   ret = context.querySelectorAll( tag || "*" );
  } else {
   ret = [];
  }
  console.log(nodeName( context, tag ),'nodeName4909')
  //nodeName() 判断两个参数的nodename是否相等
  if ( tag === undefined || tag && nodeName( context, tag ) ) {

   return jQuery.merge( [ context ], ret );
  }
  return ret;
 }

注意:DocumentFragment 没有getElementsByTagName方法,但有querySelectorAll方法!

二、$.merge()

作用:

合并两个数组内容到第一个数组

源码:

// Support: Android <=4.0 only, PhantomJS 1 only
  // push.apply(_, arraylike) throws on ancient WebKit
  //源码461行
  //将second合并到first后面
  merge: function( first, second ) {
   var len = +second.length,
    j = 0,
    i = first.length;
   //依次将second的item添加到first后面
   for ( ; j < len; j++ ) {
    first[ i++ ] = second[ j ];
   }
   //first可能是类数组,所以需要更新下length属性
   first.length = i;
   return first;
  },

需要注意的是最后的 first.length = i

三、cleanData()

作用:

清除元素节点上的事件和数据

源码:

//清除elems上的数据和事件
  //源码6146行
  cleanData: function( elems ) {
   var data, elem, type,
    //beforeunload/blur/click/focus/focusin/focusout/
    //load/mouseenter/mouseleave/pointerenter/pointerleave
    special = jQuery.event.special,
    i = 0;
   for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
    //允许的节点类型
    if ( acceptData( elem ) ) {
     //当有事件绑定到elem后,jQuery会给elem一个属性dataPriv.expando
     //该属性上面就绑定了事件和数据
     if ( ( data = elem[ dataPriv.expando ] ) ) {
      //如果data上有事件的话
      if ( data.events ) {
       //逐个列举data上的事件,比如click
       for ( type in data.events ) {
        // 如果special中有data.events上的事件
        if ( special[ type ] ) {
         //调用jQuery.event.remove方法,移除elem上的event类型
         jQuery.event.remove( elem, type );
         // This is a shortcut to avoid jQuery.event.remove's overhead
        }
        //应该是自定义的事件
        else {
         //本质即elem.removeEventListener(type,handle)
         jQuery.removeEvent( elem, type, data.handle );
        }
       }
      }
      // Support: Chrome <=35 - 45+
      // Assign undefined instead of using delete, see Data#remove
      //最后将元素的dataPriv.expando属性置为undefined
      elem[ dataPriv.expando ] = undefined;
     }
     //dataUser应该是用户绑定的事件
     if ( elem[ dataUser.expando ] ) {
      // 将元素的dataUser.expando属性置为undefined
      // Support: Chrome <=35 - 45+
      // Assign undefined instead of using delete, see Data#remove
      elem[ dataUser.expando ] = undefined;
     }
    }
   }
  }

解析:

① 依次判断 elems[i] 是否是元素节点/文档节点/对象

② 再判断 elem 的 dataPriv.expando 属性是否有 events 属性

③ 当 events 里有 jQuery.event.special 指定的 事件类型时,
使用jQuery.event.remove(elem,type)移除事件和数据

④ 反之,则使用jQuery.removeEvent(elem,type,data.handle)移除事件和数据

⑤ 将 elem[dataPriv.expando]置为 undefined

⑥ 将 elem[dataUser.expando]置为 undefined

四、acceptData()

作用:

判断是否是指定的节点类型,返回 true/false

源码:

//判断是否是指定的节点类型
 //只接受元素节点1,文档节点9,任意对象
 //返回true/false
 //源码4178行
 var acceptData = function( owner ) {
  // Accepts only:
  // - Node
  //  - Node.ELEMENT_NODE
  //  - Node.DOCUMENT_NODE
  // - Object
  //  - Any
  return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
 }

注意:

Object 类型的 nodeType 是 undefined

五、$.removeEvent()

作用:

移除 elem 上的自定义监听事件

源码:

//移除elem上的自定义监听事件
 //源码5599行
 //jQuery.removeEvent(elem,type,data.handle)
 jQuery.removeEvent = function( elem, type, handle ) {
  // This "if" is needed for plain objects
  if ( elem.removeEventListener ) {
   elem.removeEventListener( type, handle );
  }
 }

本质即调用原生JS的removeEventListener()方法

总结

以上所述是小编给大家介绍的jQuery中的getAll()和cleanData(),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

jQuery 相关文章推荐
BootStrap中jQuery插件Carousel实现轮播广告效果
Mar 27 jQuery
jQuery中的deferred对象和extend方法详解
May 08 jQuery
jQuery日期范围选择器附源码下载
May 23 jQuery
jQuery Validate格式验证功能实例代码(包括重名验证)
Jul 18 jQuery
jQuery实现腾讯信用界面(自制刻度尺)样式
Aug 15 jQuery
jQuery实现的弹幕效果完整实例
Sep 06 jQuery
jQuery选择器之子元素选择器详解
Sep 18 jQuery
jQuery自动或手动图片切换效果
Oct 11 jQuery
[原创]jQuery实现合并/追加数组并去除重复项的方法
Apr 11 jQuery
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
Jan 09 jQuery
javascript/jquery实现点击触发事件的方法分析
Nov 11 jQuery
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
详解JQuery基础动画操作
Apr 12 #jQuery
详解jQuery设置内容和属性
Apr 11 #jQuery
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
Apr 10 #jQuery
jQuery中实现text()的方法
Apr 04 #jQuery
基于 jQuery 实现键盘事件监听控件
Apr 04 #jQuery
jQuery分组选择器简单用法示例
Apr 04 #jQuery
jQuery实现带3D切割效果的轮播图功能示例【附源码下载】
Apr 04 #jQuery
You might like
php5新改动之短标记启用方法
2008/09/11 PHP
PHP中防止SQL注入方法详解
2014/12/25 PHP
php实现微信原生支付(扫码支付)功能
2018/05/30 PHP
JQuery index()方法使用代码
2010/06/02 Javascript
juqery 学习之五 文档处理 包裹、替换、删除、复制
2011/02/11 Javascript
JavaScript中自带的 reduce()方法使用示例详解
2016/08/10 Javascript
js数字舍入误差以及解决方法(必看篇)
2017/02/28 Javascript
React利用插件和不用插件实现双向绑定的方法详解
2017/07/03 Javascript
Node.js创建Web、TCP服务器
2017/12/05 Javascript
深入理解react 组件类型及使用场景
2019/03/07 Javascript
JQuery特殊效果和链式调用操作示例
2019/05/13 jQuery
使用JS判断页面是首次被加载还是刷新
2019/05/26 Javascript
Vue实现摇一摇功能(兼容ios13.3以上)
2021/01/26 Vue.js
一起来了解一下JavaScript的预编译(小结)
2021/03/01 Javascript
Mac中Python 3环境下安装scrapy的方法教程
2017/10/26 Python
Python编程django实现同一个ip十分钟内只能注册一次
2017/11/03 Python
详解Python 函数如何重载?
2019/04/23 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
python 穷举指定长度的密码例子
2020/04/02 Python
推荐值得学习的12款python-web开发框架
2020/08/10 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
Python random模块的使用示例
2020/10/10 Python
css 如何让背景图片拉伸填充避免重复显示
2013/07/11 HTML / CSS
纽约的奢华内衣店:Journelle
2016/07/29 全球购物
加拿大时尚床上用品零售商:QE Home | Quilts Etc
2018/01/22 全球购物
简单介绍Object类的功能、常用方法
2013/10/02 面试题
工业学校毕业生自荐书
2014/01/03 职场文书
毕业自我鉴定怎么写
2014/03/25 职场文书
送温暖献爱心活动总结
2014/07/08 职场文书
校外活动方案
2014/08/28 职场文书
教师批评与自我批评
2014/10/15 职场文书
聘任证明怎么写
2015/03/02 职场文书
酒店人事专员岗位职责
2015/04/07 职场文书
政工师工作总结2015
2015/05/26 职场文书
主持人大赛开场白
2015/05/29 职场文书
运动会加油稿50字
2015/07/21 职场文书