详细说明jQuery查找dom的几种方法的效率
序
这个问题是我们前端组每个人编码习惯的差异造成的,最重要的问题是代码的可维护性。在此基础上,我仔细查阅了jQuery源代码(1.11.3)中与查找dom节点相关的内容,虽然不能深入理解。同时,基于对浏览器控制台对象的理解,产生了一系列后续的问题和分析,并对jQuery中最常用的三种dom搜索方法的搜索效率和性能进行了对比分析。
首先,我们需要使用成对出现的console对象、console.time()和console.timeEnd()的方法。这个方法的用法是执行它们之间的代码段并输出消耗的执行时间,两者中的传入字符串必须统一命名才能生效。例如:
console . time(' Scott ');console . log(' seven ');console . time end(' Scott ');SevenScott: 0.256ms毫秒代码段是三个相同点的正确用法。
主体
接下来,让我们讨论查找dom的常见jQuery方法:
1.$('.父母。child’);2.$('.父代')。查找('。child’);3.$('.子代','。家长');其中,模式1和模式3是基于jQuery的选择器和上下文的搜索方式,是最常用的jQuery()或$(),具体如下:
jQuery=function(selector,context){//jQuery对象实际上只是init构造函数' enhanced' //如果调用jQuery就需要init(如果不包含只允许抛出错误)返回新的jQuery.fn.init(selector,context);}基于jquery (1.11.3)的第70行,作为这个方法的入口,他所做的只是在jquery.fn上创建一个init方法的对象,让我们仔细看看这个对象是什么:
init=jQuery.fn.init=function(选择器,上下文){ var match,elem///handle : $(' '),$(null),$(未定义)、$(false) if(!选择器){返回这个;} //处理超文本标记语言字符串if(选择器的类型==' string '){ if(选择器。charat(0)=='选择器。charat(选择器。length-1)=' '选择器。长度=3){//假设以开头和结尾的字符串都是HTML,并跳过正则表达式检查匹配=[ null,选择器,null];} else { match=rquickExpr.exec(选择器);} //匹配超文本标记语言或确保没有为#id指定上下文if (match (match[1] ||!context)){//handle : $(html)-$(array)if(match[1]){ context=jQuery的context实例?上下文[0] :上下文;//脚本对于back-compat /是真的故意让错误在parseHTML不存在的情况下抛出jQuery.merge(这个,jQuery.parseHTML(匹配[1],context.nodeType?语境。ownerdocument | | context :文档,true));//HANDLE: $(html,props)if(rsingletag。测试(匹配[1])jquery。isplayanoobject(context)){ for(context中的匹配){ //如果可能,将上下文的属性作为方法调用if(jquery。is function(this[match]){ this[match](context[match]);//.否则设置为属性} else { this。attr(match,context[match]);} } }返回此;//句柄: $(# id)} else { elem=document。getelementbyid(匹配[2]);//当黑莓4.6返回//不再在文档#6963 if (elem elem.parentNode)中的节点时,检查父节点以捕捉{ //处理工业管理学(Industrial Engineering)和歌剧返回项//按名称而不是ID if (elem.id!==match[2]){ return rootjquery。查找(选择器);} //否则,我们直接将元素注入jQuery对象这个。长度=1;this[0]=elem;} this . context=document this . selector=selector归还这个;} //HANDLE: $(expr,$(.))} else if(!上下文| |上下文。jquery){ return(context | | rootjQuery).查找(选择器);//HANDLE: $(expr,context) //(这正好相当于:美元(上下文).find(expr)} else { return this。构造函数(上下文).查找(选择器);}//HANDLE : $(DOMEnElement)} else if(选择器。nodetype){ this。context=this[0]=选择器;这个。长度=1;归还这个;//HANDLE: $(函数)//文档就绪的快捷方式} else if (jQuery.isFunction(选择器)){返回rootjQuery.ready的类型!=='未定义?rootjQuery.ready(选择器): //如果准备好的不存在,立即执行选择器(jQuery);} if (selector.selector!==未定义){这个。选择器=选择器。选择器;这个。上下文=选择器。语境;}返回jQuery.makeArray(选择器,这个);}基于jQuery(1.11.3) 2776行处,该方法比较长,我就来大概说一下我对这个方法的了解:这里主要就是做了先对选择器的判断,在判断完后,查找语境如果存在就继续做对有语境存在情况的处理,没有则进行没有语境情况的处理,而方式一和方式3:
1.$('.父母“孩子”;3.$('.子代','。家长');他们都要进入相同的判断步骤,即上面简要说明的判断流程,等到一和3判断完后所花费的时间基本差不多,但是一内部的选择器还需要花费时间去进行咝咝声相关查找,得出:
方式1.$('.父母“孩子”;走完流程花费的时间:a;方式3.$('.子代','。家长');走完流程花费的时间:a;几乎已经找到数字正射影像图节点方式1.$('.父母“孩子”;咝咝声相关查找选择器。父母。儿童花费的时间:b;所以得出初步结论:方式3.$('.子代','。家长');花费的时间:a;方式1.$('.父母“孩子”;花费的时间:a b;方式3优于方式一接下来我们来看实际的运行结果:
以百度页面为例,我们随便找出一组满足的范围来查找,博主进行多次测试,方式3的查找效率均快于方式1,且方式3的查找速度基本为方式一的3倍左右,即:
接下来,我们加入jQuery的find方法进行比较,即:
模式1。$(' . parent . child ');模式2。$ ('.父代')。查找('。child’);模式3。$ ('.子代','。家长');正如我们之前判断的那样,基于他们三个都必须搜索jQuery()的事实,他们三个都在这里花了一段搜索时间。此时,模式3已基本找到:
模式3。$ ('.子代','。家长');需要: a;接下来,找到。模式1中的“parent.child”选择器,模式2中的jQuery中的find方法,在这里列出find的具体内容:
find:函数(选择器){ var i,ret=[],self=this,len=self.lengthif(选择器的类型!=='string' ) {返回this.pushStack(jQuery(选择器))。filter(function(){ for(I=0;我透镜;i ) { if (jQuery.contains(self[ i ],this)){ return true;} } }) );} for(I=0;我透镜;i ) { jQuery.find(选择器,self[ i ],ret);} //需要,因为$(选择器,上下文)变成$(上下文)。find(选择器)ret=this.pushStack(len 1?jquery . unique(ret): ret);ret.selector=this.selector?this.selector ' '选择器:选择器;返回ret}基于jQuery (1.11.3)的第2716行,我们可以看到find的过程比较简单,比Mode 1中查找复杂的选择器效率更高(在查找选择器的过程中需要排除很多情况,更多的时间花在处理字符串上,也就是处理我们想要表达的选择器)。我们得出结论,模式2优于模式1。下面我们来比较一下:
我们可以看到,模式1最慢,模式2与模式3相当,模式3略好,基本符合我们的初衷,即:
在基于jquery搜索dom的过程中,我们可以使用jQuery的搜索方法,尽量不要编写复杂的选择器来表达我们想要查找的dom,效率极低。相反,通过使用jquery,我们可以尽可能地消除复杂的选择器,大大提高搜索效率。
因为模式2的使用可能会受到限制,所以在这里推荐大家使用模式3,即:
摘要
好了,这就是本文的全部内容。写到这里,突然觉得自己对自己没用。我写得好像我的编码能力强到可以拼写dom来寻找效率。我希望我能帮助我有需要的朋友。
版权声明:详细说明jQuery查找dom的几种方法的效率是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。