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;ilength;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,"");//將字串前後空格,用Null 字元串替代。
},
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,"");//將字串前後空格,用Null 字元串替代。
}
});
/*--------------------------------------------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);