JQury框架絕對是首先頁面開發的首選,代碼短小強悍,缺點就是面向對象特性不足,所幸有不少插件!至於Ext就是一個龐然大物了,高度面向對象,類似於MFC的龐大API和控件庫,運行起來,瀏覽器就累得夠嗆,開發也夠嗆,使用代碼來創建界面絕對是個糟糕的方式,Javascript的弱語言類型使得Ext開發就像行走在雷區,減少bug的唯一方法就是不要寫出bug,一旦出現bug,調試將是一件極爲痛苦的事情 !在幾千行代碼裏跟蹤、跳轉真讓人抓狂!
Javascript做面向對象開發的時候,總是會用到很多模擬面向對象特性的方法,這些方法就構成了支撐面向對象Javascript的核心代碼,以下就是部分代碼,其中參考了很多JQuery與Ext的核心代碼,用來學習還不錯,也可以做一些小的開發!
/*
功能:核心腳本方法
作者:LQB
2008-12-22 */ var JCore = {//構造核心對象 version:1.0, $import:function(importFile){ var file = importFile.toString(); var IsRelativePath = (file.indexOf("$")==0 ||file.indexOf("/")==-1);//相對路徑(相對於JCore) var path=file; if(IsRelativePath){//計算路徑 if(file.indexOf("$")==0) file = file.substr(1); path = JCore.$dir+file; } var newElement=null,i=0; var ext = path.substr(path.lastIndexOf(".")+1); if(ext.toLowerCase()=="js"){ var scriptTags = document.getElementsByTagName("script"); for(var i=0;ilength;i++) { if(scriptTags[i].src && scriptTags[i].src.indexOf(path)!=-1) return; } newElement=document.createElement("script"); newElement.type="text/javascript"; newElement.src=path; } else if(ext.toLowerCase()=="css"){ var linkTags = document.getElementsByTagName("link"); for(var i=0;iTags.length;i++) { if(linkTags[i].href && linkTags[i].href.indexOf(path)!=-1) return; } newElement=document.createElement("link"); newElement.type="text/css"; newElement.rel="Stylesheet"; newElement.href=path; } else return; var head=document.getElementsByTagName("head")[0]; head.appendChild(newElement); }, $dir : function(){ var scriptTags = document.getElementsByTagName("script"); for(var i=0;ilength;i++) { if(scriptTags[i].src && scriptTags[i].src.match(/JCore/.js$/)) { path = scriptTags[i].src.replace(/JCore/.js$/,""); return path; } } return ""; }(), $ : function(element){ return (typeof(element) == 'object' ? element : document.getElementById(element)); }, browser : { isFirefox:navigator.userAgent.toLowerCase().indexOf ('gecko') != -1, isChrome:navigator.userAgent.toLowerCase().indexOf ('chrome') != -1, isOpera:navigator.userAgent.toLowerCase().indexOf ('opera') != -1, isIE:navigator.userAgent.toLowerCase().indexOf ('msie') != -1, isIE7:navigator.userAgent.toLowerCase().indexOf ('7.0') != -1 }, onReady: function(newFunction){ if(typeof(newFunction) == 'undefined') return false; this.domReady = false; if(typeof(functions) == 'undefined') var functions = []; functions.push(newFunction); var initial = function(){//執行事件列表 for(var i=0; i< functions.length;i++){ functions[i](); } } this.ready = function(){//加載事件 if(this.domReady) initial(); var Browser = JCore.browser; if (Browser.isFirefox || Browser.isOpera || Browser.isChrome) {//FX try { document.removeEventListener('DOMContentLoaded', initial); }catch(e){} document.addEventListener('DOMContentLoaded', initial, false); this.domReady = true; } else if (Browser.isIE) {//IE var timer = window.setInterval(function(){ try { var IsReady = false; document.body.doScroll("left"); IsReady=true; initial(); window.clearInterval(timer); this.domReady = true; } catch (e){ if(IsReady){//文檔加載已經完畢,拋出異常說明是調用的方法出錯 var ErrorMsg = "onReady的方法中發生錯誤!/r/n"; ErrorMsg+="錯誤信息:"+e.message+"/r/n"; ErrorMsg+="錯誤描述:"+e.description+"/r/n"; ErrorMsg+="錯誤類型:"+e.name+"/r/n"; alert(ErrorMsg); window.clearInterval(timer); } } } , 5); } } this.ready(); }, apply:function(oDes, oSrc,bReplace){//爲對象拷貝其它對象的屬性,bReplace可選 if(oDes && oSrc && typeof(oSrc) == 'object'){ for(var p in oSrc){ if(bReplace == false && oDes[p] != null) { continue; } oDes[p] = oSrc[p]; } } return oDes; }, override : function(origclass, overrides){//爲類增加重載方法,eg:override(function class(){},{A:function(){},B:function(){}}); if(overrides){ var p = origclass.prototype; for(var method in overrides){ p[method] = overrides[method]; } } }, extend :function(){ // inline overrides var inlineOverride = function(o){ for (var m in o) { this[m] = o[m]; } }; /*需要實現重載的基類方法需要在父類prototype中定義; * 在子類中方法的可見度:子類構造中的屬性>父類構造中的屬性>子類prototype定義的屬性==overrides>父類prototype定義的屬性 * 由於overrides方法被附加到子類的prototype中,所以:子類prototype定義的屬性與overrides,兩者後定義的可見 * extend方法將重寫子類的prototype,因此在子類的prototype上定義屬性則必須在extend()方法調用之後再定義纔有效 * 對於一個類:構造中定義的屬性>prototype定義的屬性 * *類派生的準則: * 1.建議把基類中可重寫的方法定義在基類prototype中 * 2.如果在派生類的prototype中定義屬性方法,必須在extend()方法之後 * 3.在派生類的構造中調用基類的構造: * if(Sub.superclass) //sub即子類的名稱 * Sub.superclass.constructor.call(this, Args);//Args即父類的構造方法的參數 * 4.注意數組的淺拷貝問題 *示例: * var ClassA=function(){this.Show=function(){alert("Hello World!");}}; * var ClassB=function(){}; * JCore.extend(ClassB,ClassA); * var ObjectB = new ClassB(); * ObjectB.Show(); */ return function(subFn, superFn, overrides){//子類,父類,重載方法(可選) var F = function(){}, subFnPrototype, superFnPrototype = superFn.prototype; F.prototype = superFnPrototype; subFnPrototype = subFn.prototype = new F(); subFnPrototype.constructor = subFn; subFn.superclass = superFnPrototype;//父類 if (superFnPrototype.constructor == Object.prototype.constructor) { superFnPrototype.constructor = superFn; } subFn.override = function(obj){//override JCore.override(subFn, obj); }; subFnPrototype.override = inlineOverride; if(overrides) JCore.override(subFn, overrides); return subFn; }; }(),//括號不可少,表示調用內部返回的方法 namespace : function(ns){//eg: JCore.namespace("JCore", "JCore.util"); var args=arguments, o=null, i, j, d, rt; for (i=0; ilength; ++i) {//遍歷參數 d=args[i].split(".");//遍歷點分隔符 rt = d[0]; eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';'); for (j=1; jlength; ++j) { o[d[j]]=o[d[j]] || {}; o=o[d[j]]; } } }, isEmpty : function(value){ return value === null || typeof(value) === 'undefined' || value === ''; }, idSeed : 0, id : function(el, prefix){ prefix = prefix || "JCore-gen"; el = this.$(el); var id = prefix + (this.idSeed++); return el ? (el.id ? el.id : (el.id = id)) : id; } }; /*--------------------------------------------Function對象擴展-------------------------------------------*/ var FunctionExtendMethod ={ createCallback : function(/*args...*/){//此參數即創造者的參數 /*示例:function func1(arg1,arg2){alert(arg1+arg2);} * var myfunc = func1.createCallback(1,2); * myfunc();//即調用了func1 **/ var args = arguments; var method = this; return function(/*args...*/) {//如果在調用時傳了參數,則創建時傳的參數無效 var callArgs = arguments.length>0 ? arguments : args; return method.apply(window, callArgs); }; }, createDelegate : function(argsArray,scope){//參數可選 //參數一個數組,與createCallback區別:createCallback參數是可變參數,createDelegate的argsArray參數必須是數組 var method = this; return function(/*args...*/) {//如果在調用時傳了參數,則創建時傳的參數無效 var callArgs = typeof(argsArray)=="undefined"?[]:argsArray; callArgs = arguments.length>0 ? arguments : callArgs; return method.apply(scope||window, callArgs); }; }, defer : function(millis/*,args...*/){//參數:延遲時間(毫秒),可選參數列表 /*示例:function func1(arg1,arg2){alert(arg1+arg2);} * func1.defer(1000,1,2);//延遲1秒調用了func1(1,2) **/ var callArgs = Array.prototype.slice.call(arguments, 1); var fn = this.createDelegate(callArgs); if(millis){ return setTimeout(fn, millis); } fn(); return 0; }, createInterceptor : function(fcn, scope){ if(typeof fcn != "function"){ return this; } var method = this; return function() { fcn.target = this; fcn.method = method; if(fcn.apply(scope || this || window, arguments) === false){ return; } return method.apply(this || window, arguments); }; } }; JCore.apply(Function.prototype,FunctionExtendMethod); /*--------------------------------------------String對象擴展----------------------------------------*/ var StringExtendMethod ={ trim : function(){//去掉首尾空格 return this.replace(/(^/s*)|(/s*$)/g,"");//將字符串前後空格,用空字符串替代。 }, replaceAll : function (AFindText,ARepText){//替換所有,replace只替換第一個 raRegExp = new RegExp(AFindText,"g"); return this.replace(raRegExp,ARepText); }, htmlEncode : function(){//編碼HTML和解碼Html。過濾掉雙引號,單引號,符號&,符號<,符號 return this.replace(/&/g,"&").replace(/,"<").replace(/>/g,">").replace(//"/g,""").replace(//'/g,"'"); }, htmlDecode : function(){ return this.replace(//&/;/g, '/&').replace(//>/;/g, '/>').replace(//</;/g, '/<').replace(//"/;/g, '/'').replace(//&/#39/;/g, '/''); }, format : function(){ var args=arguments; return this.replace(//{(/d+)/}/g, function(m, i){ return args[i]; }); }, convertWarpSymbol : function(){ var reg1,reg2,reg3; if(this.toLowerCase().indexOf("
")!=-1){ reg1 = / /gi; reg2 = //gi; return this.replace(reg1," ").replace(reg2,"/r/n"); } else{ reg1 = / /g;reg2 = //r/n/gi; return this.replace(reg1," ").replace(reg2,"
"); } }, IsNum : function(){ var reg = /^/d+$/g; return reg.test(this); } }; JCore.apply(String.prototype,StringExtendMethod); JCore.apply(String,{//靜態方法 trim : function(str){//去掉首尾空格 return str.replace(/(^/s*)|(/s*$)/g,"");//將字符串前後空格,用空字符串替代。 } }); /*--------------------------------------------Array對象擴展----------------------------------------*/ var ArrayExtendMethod ={//去掉數組中重複的元素 strip : function(){ if(this.length<2) return [this[0]]||[]; var arr=[]; for(var i=0;i<this.length;i++){ var repeat=false; for(var j=0;jlength;j++){ if(this[i]===arr[j]) repeat=true; } if(!repeat) arr.push(this[i]); } return arr; }, exists : function(item){ for( var i = 0 ; i < this.length ; i++ ){ if( item === this[i]) return true; } return false; }, indexOf : function(item){ for (var i = 0; i < this.length; i++){ if(this[i] === item) return i; } return -1; }, remove : function(item){ var index = this.indexOf(item); if(index != -1){ this.splice(index, 1); } return this; } }; JCore.apply(Array.prototype,ArrayExtendMethod); /*--------------------------------------------Date對象擴展----------------------------------------*/ var DateExtendMethod ={//返回時間間隔(毫秒) getElapsed : function(date) { return Math.abs((date || new Date()).getTime()-this.getTime()); } }; JCore.apply(Date.prototype,DateExtendMethod);