详解jQuery中的getAll()和cleanData()
前言:
看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行 functiongetAll(context,tag){ //Support:IE<=9-11only //Usetypeoftoavoidzero-argumentmethodinvocationonhostobjects(#15151) varret; console.log(context,typeofcontext.getElementsByTagName,typeofcontext.querySelectorAll,'context4894') //如果context存在getElementsByTagName的方法的话 if(typeofcontext.getElementsByTagName!=="undefined"){ //tag:script //从context中获取script标签的节点 ret=context.getElementsByTagName(tag||"*") console.log(tag,ret,'ret4897') } //DocumentFragment没有getElementsByTagName方法,但有querySelectorAll方法 elseif(typeofcontext.querySelectorAll!=="undefined"){ ret=context.querySelectorAll(tag||"*"); }else{ ret=[]; } console.log(nodeName(context,tag),'nodeName4909') //nodeName()判断两个参数的nodename是否相等 if(tag===undefined||tag&&nodeName(context,tag)){ returnjQuery.merge([context],ret); } returnret; }
注意:DocumentFragment没有getElementsByTagName方法,但有querySelectorAll方法!
二、$.merge()
作用:
合并两个数组内容到第一个数组
源码:
//Support:Android<=4.0only,PhantomJS1only //push.apply(_,arraylike)throwsonancientWebKit //源码461行 //将second合并到first后面 merge:function(first,second){ varlen=+second.length, j=0, i=first.length; //依次将second的item添加到first后面 for(;j需要注意的是最后的first.length=i
三、cleanData()
作用:
清除元素节点上的事件和数据
源码:
//清除elems上的数据和事件 //源码6146行 cleanData:function(elems){ vardata,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(typeindata.events){ //如果special中有data.events上的事件 if(special[type]){ //调用jQuery.event.remove方法,移除elem上的event类型 jQuery.event.remove(elem,type); //ThisisashortcuttoavoidjQuery.event.remove'soverhead } //应该是自定义的事件 else{ //本质即elem.removeEventListener(type,handle) jQuery.removeEvent(elem,type,data.handle); } } } //Support:Chrome<=35-45+ //Assignundefinedinsteadofusingdelete,seeData#remove //最后将元素的dataPriv.expando属性置为undefined elem[dataPriv.expando]=undefined; } //dataUser应该是用户绑定的事件 if(elem[dataUser.expando]){ //将元素的dataUser.expando属性置为undefined //Support:Chrome<=35-45+ //Assignundefinedinsteadofusingdelete,seeData#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行 varacceptData=function(owner){ //Acceptsonly: //-Node //-Node.ELEMENT_NODE //-Node.DOCUMENT_NODE //-Object //-Any returnowner.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"isneededforplainobjects if(elem.removeEventListener){ elem.removeEventListener(type,handle); } }本质即调用原生JS的removeEventListener()方法
总结
以上所述是小编给大家介绍的jQuery中的getAll()和cleanData(),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!