公司一直使用 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
數組