时隔这么几个月,再次写一下jQuery中的一些东西,这里想要说的是jQuery中的链式操作。它让代码变得更有层次更简洁。
概况这里就先说一下jQuery中链式操作的基础,其根本思想就是在利用构造函数在做这个处理,那么如果想要更好的理解下面的内容,最好要对构造函数有一些基本的认识才行,如果您对构造函数以及构造函数的实例化的认识不多,那么请先看之前的一篇文章,可以让您对构造函数有一个基本的认识,并拥有足够的知识让您继续看下面的内容,了解到jQuery中的链式操作的实现方法。
自定义创建对象的几种方法,对象继承的方法小结,原型链断链的原因
简化的实例我个人在想说明一些代码的实现思想时,总会以最简单的实例来说明某个问题,现在依然是使用最简单的一个实例来说明,下面的代码是取自jQuery源码中的实现:
var rootjQuery = null, //rootjQuery只是用于jQuery函数中的第三个参数,预定义的 //在这里,是没有意义的。 jQuery = function( selector, context ) { //jQuery方法,也就是我们常用的选择器$符。 //在jQuery中,我们每次使用$或者jQuery进行元素选择时 //都会调用该方法,返回一个包含目标元素的类数组 return new jQuery.fn.init( selector, context, rootjQuery ); //当调用jQuery时,则对jQuery.fn.init函数进行实例化 //并把该实例当做返回值。 //返回的实例中,包含init函数的实例属性和方法, //以及原型链中的属性和方法。 }; //jQuery.fn = jQuery.prototype //这里,jQuery中的代码是上面注释掉的这个, //但是对于我们这里要说的问题,可以只使用下面的方法即可 jQuery.fn = { //这里给jQuery定义一个静态对象fn(其实应该成为静态属性), //并且这个方法内部包含init和toArray方法 init: function( selector, context, rootjQuery ) { console.log("jQuery.init"); }, toArray: function() { console.log("jquery.toArray"); } }; jQuery.fn.init.prototype = jQuery.fn; //这里就是链式操作的开始 //前面也说了,当调用jQuery方法时 //返回了jQuery.fn.init函数的一个实例 //那么在构造函数的实例中,就可以访问构造函数中prototype中的属性和方法 //所以,当我们每次调用jQuery()进行操作时,返回的一个实例中,都可以调用jQuery.fn中所包含的所有的方法。 //所以,我们就可以这样的调用:jQuery().init();jQuery().toArray(); jQuery().init(); //jQuery.init //jQuery.init jQuery().toArray(); //jQuery.init //jQuery.toArray按照上面的写法,所谓的链式操作也就在这里借宿了,很明显,这并不是jQuery当前实现的样子,那么如何能多次进行链式操作呢。
这里就需要懂得一点,看下面这种写法:
var name = "zhangzhang", obj = { name:"zhang", getName:function(){ return this.name; } }; console.log(obj.getName());对于上述代码中的this指代的是哪个对象呢?
懂得了上述中this的指代,那么我们之前想要解决的问题,也就很简单了。
只需要对需要继续支持链式操作的方法,有一个返回值即可。
所以代码修改为如下样式:
var rootjQuery = null, jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }; jQuery.fn = jQuery.prototype = { init: function( selector, context, rootjQuery ) { console.log("jQuery.init"); return this; }, toArray: function() { console.log("jquery.toArray"); return this; } }; jQuery.fn.init.prototype = jQuery.fn; jQuery().init().init().toArray().init().toArray(); //控制台打印的结果如下: //jQuery.init //jQuery.init //jQuery.init //jquery.toArray //jQuery.init //jquery.toArray到这里,关于链式操作的原理代码,也就介绍了,我都是按照自己的理解,进行的简单的说明,如有问题,请指点。
jQuery的第二个参数不知道你有没有注意到一点,就是jQuery方法是可以传入两个参数的,那第二个参数是如何使用的呢,下面就看下如何使用第二个参数:
先看个例子,html布局部分如下:
<div id ="test"> <div class = "item">test1</div> <div class = "item">test2</div> <div class = "item">test3</div> </div>那么我们想要查找id=test元素下的所有的class=item的元素,通常情况下,我们会使用的方法是:jQuery("#test .item");
但是,我们有时候,我们也需要对id=test的元素进行一些处理,所以,我们首先要做的就是要先把id=test的元素取出来,并且还需要id=test元素下class=item的元素,通常我们有以下多种方法:
var test = jQuery("#test"), allDiv = jQuery("#test .item"); console.log(test); console.log(allDiv); //该方法的不好之处在于当取allDiv时,又再次查找了id=test的元素 //这样肯定效率相对较低 //试想要去一个小区找人,要先找到在哪栋楼,然后在该楼再找到在哪个房间。 //这里的id=test就是那栋楼,如果我们已经知道了在那栋楼, //还依然从整个小区的规模去找,那么效率肯定就会相对较低了 //所以,才有下面的方法 allDiv = test.children(".item"); console.log(allDiv); //该方法,就是,在寻找class=item的时候,是以id=test的元素开始的 //就想比于,找人是从一栋楼开始的,相对于前一种写法,有更高的效率 //但是有个缺点仍然是,它只能查找直接子元素。 //所以就有了下一种方法 allDiv = test.find(".item"); console.log(allDiv); //这个本来是我认为最常用的方法了吧,当然,是使用find方法还是使用children方法,主要还是看,你要查找的范围是在一个怎么样的范围。 //现在看了jQuery实现的方法,那么就又看到了另外一个寻找子元素的方法了 //注意到了没,jQuery函数是可以接受第二个参数的,那么第二个参数是代表了什么意思呢? //就是范围的意思,在这个范围的基础上,查找第一个参数的所要匹配的元素 //所以,这里可以这么来查找 allDiv = jQuery(".item",test); console.log(allDiv); //由结果可以看出,它是完成了和find相同的功能, //当然,这里的第二个参数也可以直接以字符串的形式书写。 //写法如下: allDiv = jQuery(".item","#test"); console.log(allDiv); //获取到的结果,和前面的一样, //只是如果是这样的写法, //我们当然还是喜欢最简单的一个参数的组合写法了, //所以这个我觉得是没有太大的意义的 //而这里因为这种方法的功能和find方法,完成的是相同的功能, //而我这里也还不能验证,哪种方法,性能更优 //当然,如果是写法的话,find方法更符合jQuery的主流写作方法 //所以,这里只是想说明一下,jQuery的选择器方法, //其实是支持第二个参数的注:2014.9.20