详解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 extend()详解及简单实例
May 06 jQuery
jQuery插件ImgAreaSelect实现头像上传预览和裁剪功能实例讲解一
May 26 jQuery
基于jQuery实现的Ajax 验证用户名唯一性实例代码
Jun 28 jQuery
jQuery上传插件webupload使用方法
Aug 01 jQuery
jqueryUI tab标签页代码分享
Oct 09 jQuery
jquery写出PC端轮播图实例
Jan 26 jQuery
在Vue项目中引入JQuery-ui插件的讲解
Jan 27 jQuery
详解jQuery中的getAll()和cleanData()
Apr 15 jQuery
Easyui 去除jquery-easui tab页div自带滚动条的方法
May 10 jQuery
jquery+css实现Tab栏切换的代码实例
May 14 jQuery
jQuery实现全选按钮
Jan 01 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
php微信公众平台开发(三)订阅事件处理
2016/12/06 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
Laravel find in set排序实例
2019/10/09 PHP
jQuery实现带滚动线条导航效果的方法
2015/01/30 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
Angular外部使用js调用Angular控制器中的函数方法或变量用法示例
2016/08/05 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
详解React native全局变量的使用(跨组件的通信)
2017/09/07 Javascript
Node.js动手撸一个静态资源服务器的方法
2019/03/09 Javascript
详解Node.js异步处理的各种写法
2019/06/09 Javascript
通过说明与示例了解js五种设计模式
2019/06/17 Javascript
JavaScript中Dom操作实例详解
2019/07/08 Javascript
vue webpack重写cookie路径的方法
2019/07/10 Javascript
Elementui表格组件+sortablejs实现行拖拽排序的示例代码
2019/08/28 Javascript
webpack + vue 打包生成公共配置文件(域名) 方便动态修改
2019/08/29 Javascript
p5.js实现动态图形临摹
2019/10/23 Javascript
javascript实现简单打字游戏
2019/10/29 Javascript
浅谈vuex为什么不建议在action中修改state
2020/02/02 Javascript
js实现小时钟效果
2020/03/25 Javascript
Django添加sitemap的方法示例
2018/08/06 Python
使用Python函数进行模块化的实现
2019/11/15 Python
python中p-value的实现方式
2019/12/16 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
2020/03/25 Python
Python如何爬取b站热门视频并导入Excel
2020/08/10 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
凯特·丝蓓英国官网:Kate Spade英国
2016/11/07 全球购物
美国礼品卡交易网站:Cardpool
2018/08/27 全球购物
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
学术会议欢迎词
2014/01/09 职场文书
捐助倡议书范文
2014/04/15 职场文书
我的祖国演讲稿
2014/05/04 职场文书
环保建议书100字
2014/05/14 职场文书
工作证明格式及范本
2014/09/12 职场文书
2014年销售工作总结
2014/12/01 职场文书
朋友聚会开场白
2015/06/01 职场文书
Python使用Beautiful Soup(BS4)库解析HTML和XML
2022/06/05 Python