仿jQuery之链式调用
链式调用的形式其实就是对象调用一连串的方法。为什么能连续调用这么多的方法?因为调用方法返回调用的对象,于是乎就可以一如既往,一往无前地调用下去。链式调用的原理就是在方法中返回执行上下文this,每次调用完方法就像散文一样形散而神不散。链式调用有化腐朽为神奇的功效,一来可以节省代码,二来美观实用神奇,三来整洁有序,不失大将之风。下面以Link类为例:调用四个方法却始终返回new Link(),相信这个例子很容易理解。
var Link = function (){}; Link.prototype = { method1: function (){return this;}, method2: function (){return this;}, method3: function (){return this;}, method4: function (){return this;} } new Link().method1().method2().method3().method4();
明白原理之后,下面真正来体验下jQuery的链式调用。用htmlElementsArray存放着选中的html元素。这里写了筛选class,id选择器的构造方法。
var Link = function (name){ this.htmlElementsArray = [];
if(typeof name !== 'string' && typeof name !== 'object') { throw new Error('Name must be a string or a object!'); }else{ if(/\./.test(name)){ var obj = document.getElementsByClassName(name.substr(1)); for(var i = 0, len = obj.length; i < len; i++) { this.htmlElementsArray.push(obj[i]); } }else if(/#/.test(name)){ this.htmlElementsArray.push(document.getElementById(name.substr(1))); }else{ this.htmlElementsArray.push(name); } } }
each方法:
Link.prototype = { each: function (fn) { for(var i = 0, len = this.htmlElementsArray.length; i < len; i++) { fn.call(this, this.htmlElementsArray[i]); } return this; } }
添加addClass方法,调用each时返回this,运用了链式原理。
addClass: function (string){ this.each(function (ele){ ele.className += " "+string;
//$(this) }); return this; }
css方法添加样式,show方法显示元素,hide隐藏元素,on进行事件监听。
css: function (property, value) { this.each(function (ele){ ele.style[property] = value; }); return this; }, show: function (){ this.each(function (ele){ ele.style.display = 'block'; }); return this; }, hide: function (){ this.each(function (ele){ ele.style.display = 'none'; }) return this; }, on: function (type, fn, useCaptrue){ this.each(function (ele) { window.addEventListener ? ele.addEventListener(type, fn, useCaptrue || false) : ele.attachEvent('on' + type, fn); }); return this; }
最后封闭在$方法里。
var $ = function (name){ return new Link(name); }
我们赶紧来试下来吧!
$('.syc').addClass('yes').css('background', 'red').show().on('click', function (){ $(this).hide(); }, false);