本身寫的一個輕量級javascript框架的設計模式

公司一直使用
jQuery
框架,一些小的項目仍是以爲jQuery框架太過於強大了,因而本身週末有空琢磨着寫個本身的框架。談到js的設計模式,不得不說說js的類繼承機制,
javascript
不一樣於PHP能夠輕鬆的實現類繼承,不過
javascript
的類繼承方法仍是有的,常見的有構建函數、原型擴展、綜合……,也有一些專門寫類的函數,例如jQuery的做者有個類繼承函數。關於類繼承寫法能夠簡單看看


我本身寫的框架也不知道叫什麼名字,剛開始寫的時候隨手寫了個W(姓拼音,以前寫過jQuery彈出框插件wBox),如今寫這篇文章從新整理了一下思想,換了YQ(名字拼音,你懂的~)。javascript

核心代碼

框架設計的時候儘可能作到了支持鏈式寫法,也就是返回this,能夠$(selector).handler1().handler2()……無限寫下去,只要不是有返回值的就能夠繼續。包括了event,dom,css,還有fadeIn,fadeOut動畫(由於再重構愛牆[html5+css3]版,全部順手加上了這個功能)。若是配合sizzle選擇器就更牛了!css

下面說說框架的核心代碼,等完善了以後跟新版html5愛牆一塊兒放出,主要的代碼以下:html

(function(window,document){
	var DOC = document,YQ = window.$ = function(selector){
		if(!selector){
			return YQ.elems
		}
		typeof selector === 'string' && (selector = getElements(selector));//簡單的判斷是dom對象,仍是字符串,字符串則開始選擇器
		return superElems(selector);
	}
	function superElems(elems){
		if(elems){
			if(elems.nodeType){//判斷是否爲DOM
				if(typeof elems.getAttribute !=="unknown"){
					var temp = elems;
					elems = [];
					elems[0] = temp;//把自己做爲超級對象的第一個,其餘方法進行擴展
					for(var i in YQ.elems){
						//擴展對象,保留已有的方法
						typeof elems[i] === "undefined" && (elems[i] = YQ.elems[i])
					}
				}
			}else{//若是爲對象,則對對象進行擴展
				elems = YQ.extend(elems,YQ.elems);
			}
		}
		return elems;
	}
	function getElements(selector){
		//偉大的選擇器,可使用sizzle
		var dom = DOC.getElementById(selector);//……
		return dom;
	}
	YQ.tool = {
		isFunction:function(obj){//簡單的判斷是否爲函數
			return obj && typeof obj ==="function";
		}
	}
	//此處爲超級對象一些擴展
	YQ.elems = {
		each:function(dom,callback){//強大的each
			if(YQ.tool.isFunction(dom)){
				arguments.callee.call(this,this,dom);
			}else{
				for (var i = 0, len = dom.length; i < len; i++) {
					callback.call(dom, i, dom[i]);
				}
			}
			return this;
		},
		find:function(selector){
			var doms = [];
			this.each(function(i,dom){
				doms.push(YQ.DOM.find(selector,dom));
			})
			return superElems(doms);
		}
	}
	YQ.each = window.Array.prototype.each = YQ.elems.each;//擴展Array
	YQ.extend = function(subClass,baseClass){
		for(var i in baseClass){
			subClass[i] = baseClass[i];
		}
		return subClass;
	}
	YQ.AJAX = {}
	YQ.CSS = {
		names:{
			'float':'cssFloat',//區分cssFloat or styleFloat
			opacity:'opacity'
			//……
		}
	}
	YQ.browser = {
		isIE:'',
		isFirefox:'',
		version:'3.6'
		//……
	}
	YQ.event = {
		names:{
			mousewheel:YQ.browser?"DOMMouseScroll":"mousewheel"
		},
		fix:function(e){
			if(e && e.clone) return e;//若是已經處理了,直接返回
			e = window.event || e;//event是全局變量
			var fixE = {
				clone:true,
				stop:function(){//冒泡
					if(e&&e.stopPropagation){
						e.stopPropagation();
					}else{
						e.cancleBubble = true
					}
				},
				prevent:function(){//默認動做
					if(e && e.preventDefault){
						e.preventDefault();
					}else{
						e.returnValue = false;
					}
				},
				target:e.target || e.srcElement,
				x:e.clientX || e.pageX,
				Y:e.clientY || e.pageY,
				//鼠標滾輪事件統一處理
				wheel:e.wheelDelta/120 || -e.detail/3
			}
			return fixE;
		}
	}
	YQ.DOM = {
		find:function(selector,parentDom){
			//do something
		}
	}})(window,document);

簡單的分析

代碼中的註釋還算詳細,結合註釋就能夠看懂,下面我再多說幾句,高手飄過,歡迎拍磚……
總得來看是個匿名函數,定義了全局變量$(彷佛都喜歡美圓,若是有喜歡的人民幣的,下次加上),函數裏面有個YQ的對象,有不少function,包括一些私有的。html5

使用$能夠做爲選擇器,若是爲空,則返回YQ.elems對象,選擇後的DOM根據YQ.elems進行擴展,最後獲得的就是註釋裏面說的superElems(此處建立superElems方法參考了下jRaiser),跟jQuery的superElems相似,綁定了不少方法,能夠方便的進行操做,YQ的方法能夠經過YQ.elems擴展到選擇器選擇的對象上去,而選擇器主要的函數getElements,可使用sizzle,這樣就方便了dom操做,不過sizzle彷佛也是代碼太多,此處未來會支持簡單的標籤,#ID,.class,標籤+class選擇器。java

另外框架中中對一些Array,string進行了擴展,例如上面的Array.each方法,YQ.elems.each是重量級的函數方法,能夠支持superElems的遍歷(返回自己),還能夠支持簡單數組的遍歷。node

框架中還對一些兼容性進行了處理,例如YQ.event.fix處理事件,css中處理floatjquery

基本就這些了,今天就先說核心的部分,其實經過這段代碼已經很清晰的瞭解到這個框架的思想了,後續繼續給力的coding,補充擴展……
目前爲止,框架不到800行代碼,包括了常見的jQuery方法,壓縮後不到9k,gzip 4.5K~css3

查看更多:設計模式

http://www.gwdang.com/app/extension
數組


http://www.gwdang.com

相關文章
相關標籤/搜索