框架设计---主体函数
JS 这个后产物种真的是让人纠结。现在的狠多人用JQUERY。但jquery对模块管理,依赖管理。已经需求加载。这些都无视了。GG的closure YAHOO!的 YUI没有哪个象他那样大胆的捆绑那么多的方法到一个整个文件而且又对函数不进行区块分离。以至于jquery天生就不能用到大项目。插件的缺失。(有人说jquery的插件多如牛毛,可是垃圾插件比牛毛还多。。你的系统不臃肿么???)很多人喜欢它是因为它的接口很好。一口多用。即可以设置,又可以读取,设置可以多手段。取出的又很实际。这样的接口现在很多的公司也开始模仿。我在想做的就是在JQUERY的接口思路上。用closure DOJO YUI这样的大型架构思路来做个自己的库。选择器这样的东西基本随便找个库都有吧。可是接口人们总是觉得不爽。我开始发现自己工作之后的时间不仅仅是可以用来打个DOTA-酱油。我们需要不断努力。一起做出非常棒的插件。看看jquery的成就。相信。我在我师傅的指导下。一定成功。
下面是主体控制函数和一些公用方法。包括 抛异常,打日志。扩展,遍历。设置方法模型路径。获取模型(之前必须设置才可以获取不然抛异常)判断(数据)。
1 (function(window,undefined){
2 var _toString = {}.toString,
3 _is,
4 _writeScript,
5 _listUrl,
6 _scriptMap = {
7 method_url : {},// method --> url < method : url > < 1 : 1 >
8 url_method : {},// url --> method < url : [method,method] > < 1 : n >
9 visited : {},
10 writted : {},
11 wait_write:[]
12 },
13 _readyFnx = [],
14 alfred = function(){//自己单独使用也可以。象jquery
15 alfred.ready.apply(window,arguments);
16 };
17 //私有函数开始
18 _is = function(it,type){//复杂的可以自己进行设置。正则匹配。
19 return type.test(_toString.call(it).toLowerCase());
20 };
21 _waitReady = function(){
22 //等结束。如果结束了。直接跳出循环。其实就是利用JS的这个特性。
23 if(document.readyState != "loaded" && document.readyState != "complete")
24 {
25 var time = setTimeout(arguments.callee,0);
26 return;
27 }
28 clearTimeout(time);
29 }
30 _checkReady = function(){
31 //处理参数
32 for(var i=0;i<arguments.length;i++)
33 {
34 _readyFnx.push(arguments[i]);
35 }
36 var callback = _readyFnx.shift();
37 //支持高级事件的
38 if(document.addEventListener)
39 {
40 document.addEventListener("DOMContentLoaded",function(){
41 _waitReady();
42 document.removeEventListener("DOMContentLoaded",arguments.callee,false);
43 callback.apply(window,_readyFnx);
44 });
45 return this;
46 }
47 // 支持事件则用事件处理 IE
48 if(document.attachEvent)
49 {
50 document.attachEvent( "onreadystatechange", function(){
51 _waitReady();
52 document.detachEvent( "onreadystatechange",arguments.callee);
53 callback.apply(window,_readyFnx);
54 });
55 return this;
56 }
57 //不支持的则看不在 iframe 下时候的特殊属性。看 JSCRIPT MSDN。
58 if(document.documentElement.doScroll && window == window.top)
59 {
60 try
61 {
62 document.documentElement.doScroll("left","top");
63 }
64 catch(e)
65 {
66 setTimeout(arguments.callee, 0);
67 return;
68 }
69 callback.apply(window,_readyFnx);
70 return this;
71 }
72 };
73 _listUrl = function(){
74 var l = _scriptMap.visited,i;
75 //对我们的URL 进行筛选 。主要防止多次添加访问过的依赖库。
76 for(i in l){
77 if(!_scriptMap.writted[i])
78 {
79 _scriptMap.wait_write.push(i);
80 }
81 }
82 _scriptMap.wait_write.reverse();
83 _writeScript();
84 };
85 _writeScript = function(){
86 //写入我们的JS 了。
87 var head = document.getElementsByTagName("head").item(0),len = _scriptMap.wait_write.length;
88 for (var i;_scriptMap.wait_write.length&&(i=_scriptMap.wait_write.shift());) {
89 var script = document.createElement("script"),
90 url = i || "";
91 script.setAttribute("async",true);//高级浏览器支持HTML5特性
92 script.setAttribute("type","text/javascript");
93 script.setAttribute("src",url);
94 head.appendChild(script);
95 _scriptMap.writted[url] = true;//这里无所谓,只要有这个URL就可以
96 };
97 };
98 alfred.extend = function(){
99 var deep = false,
100 len,
101 options, name, src, copy, copyIsArray, clone,
102 target = arguments[0] || {},
103 i = 1;
104 len = arguments.length;
105 if (!len)
106 {
107 return this;
108 }
109 if(alfred.isBoolean(target))
110 {
111 deep = arguments[0];
112 to = arguments[1];
113 i = 2;
114 }
115 if (!(alfred.isObject(target) || alfred.isFunction(target))) {
116 target = {};
117 }
118 if (len = i)
119 {
120 target = this;
121 --i;
122 }
123 for (;i<len;i++) {
124 if ((options=arguments[i])!==null)
125 {
126 for (name in options) {
127 copy = options[name];
128 src = target[name];
129 if(src){throw "Becareful : you are rewrite the "+_handle+"."+name+"!"}
130 if (copy===target) {continue}
131 if (deep && copy && (alfred.isObject(copy) || (copyIsArray = alfred.isArray(copy))))
132 {
133 if (copyIsArray)
134 {
135 copyIsArray = false;
136 clone = src && alfred.isArray(src) ? src : [];
137 }
138 else
139 {
140 clone = src && alfred.isObject(src) ? src : [];
141 }
142 target[ name ] = alfred.extend( deep, clone, copy );
143 }
144 else if ( copy !== undefined )
145 {
146 target[name] = copy;
147 }
148 }
149 }
150 }
151 };
152 alfred.isNumber = function(it){return _is(it,/^\[object number\]$/)};
153 alfred.isString = function(it){return _is(it,/^\[object string\]$/)};
154 alfred.isFunction = function(it){return _is(it,/^\[object function\]$/)};
155 alfred.isObject = function(it){return _is(it,/^\[object object\]$/)};
156 alfred.isArray = function(it){return _is(it,/^\[object array\]$/)};
157 alfred.isBoolean = function(it){return typeof it ==='boolean'};
158 alfred.isDom = function(it){return _is(it,/^\[object html\w+\]$/)};
159
160 alfred.extend({
161 author : "alfred",
162 version : 1.01,
163 global : window,
164 doc : window.document,
165 reset : function(it){alfred.global[it]=alfred;},
166 log : function()
167 {
168 if(window.console && console.log)
169 {
170 return console.log.apply(window,arguments)
171 }
172 },
173 error : function(name,value)
174 {
175 throw {"name":name,"message":value};
176 },
177 require : function(method)
178 {
179 var m2u = _scriptMap.method_url,
180 u2m = _scriptMap.url_method,
181 r;
182 if(!(m2u[method])){throw "Error : you need setMethod first"}
183 if (!_scriptMap.visited[m2u[method][0]] && !_scriptMap.writted[m2u[method][0]]) {
184 //haven't be visited or write
185 _scriptMap.visited[m2u[method][0]] = true;
186 //use an beautiful code in here
187 for(; m2u[method][1].length &&(r=m2u[method][1].shift());)
188 {
189 alfred.require(r);
190 }
191 _listUrl();
192 }
193 },
194 setMethod : function(url,method,rely)
195 {
196 var i, method = alfred.isArray(method)? method:[method],
197 rely = alfred.isArray(rely)?rely:[rely];
198 if (url && !_scriptMap.url_method[url]){
199 _scriptMap.url_method[url] = method;
200 for (;method.length&&(i=method.shift());) {
201 _scriptMap.method_url[i] = {"0" : url, "1" : rely};
202 }
203 return this;
204 }
205 throw "Error : you are setMethod in an old method";
206 },
207 ready : function(){
208 _checkReady.apply(window,arguments);
209 },
210 each : function(arg,callback){
211 for(var i in arg){
212 if(arg[i])
213 {
214 callback.call(arg[i],i);
215 }
216 }
217 return arg;
218 }
219 });
220 window.alfred = alfred;
221 })(window)
1 (function(window,undefined){
2 var _toString = {}.toString,
3 _is,
4 _writeScript,
5 _listUrl,
6 _scriptMap = {
7 method_url : {},// method --> url < method : url > < 1 : 1 >
8 url_method : {},// url --> method < url : [method,method] > < 1 : n >
9 visited : {},
10 writted : {},
11 wait_write:[]
12 },
13 _readyFnx = [],
14 alfred = function(){//自己单独使用也可以。象jquery
15 alfred.ready.apply(window,arguments);
16 };
17 //私有函数开始
18 _is = function(it,type){//复杂的可以自己进行设置。正则匹配。
19 return type.test(_toString.call(it).toLowerCase());
20 };
21 _waitReady = function(){
22 //等结束。如果结束了。直接跳出循环。其实就是利用JS的这个特性。
23 if(document.readyState != "loaded" && document.readyState != "complete")
24 {
25 var time = setTimeout(arguments.callee,0);
26 return;
27 }
28 clearTimeout(time);
29 }
30 _checkReady = function(){
31 //处理参数
32 for(var i=0;i<arguments.length;i++)
33 {
34 _readyFnx.push(arguments[i]);
35 }
36 var callback = _readyFnx.shift();
37 //支持高级事件的
38 if(document.addEventListener)
39 {
40 document.addEventListener("DOMContentLoaded",function(){
41 _waitReady();
42 document.removeEventListener("DOMContentLoaded",arguments.callee,false);
43 callback.apply(window,_readyFnx);
44 });
45 return this;
46 }
47 // 支持事件则用事件处理 IE
48 if(document.attachEvent)
49 {
50 document.attachEvent( "onreadystatechange", function(){
51 _waitReady();
52 document.detachEvent( "onreadystatechange",arguments.callee);
53 callback.apply(window,_readyFnx);
54 });
55 return this;
56 }
57 //不支持的则看不在 iframe 下时候的特殊属性。看 JSCRIPT MSDN。
58 if(document.documentElement.doScroll && window == window.top)
59 {
60 try
61 {
62 document.documentElement.doScroll("left","top");
63 }
64 catch(e)
65 {
66 setTimeout(arguments.callee, 0);
67 return;
68 }
69 callback.apply(window,_readyFnx);
70 return this;
71 }
72 };
73 _listUrl = function(){
74 var l = _scriptMap.visited,i;
75 //对我们的URL 进行筛选 。主要防止多次添加访问过的依赖库。
76 for(i in l){
77 _scriptMap.wait_write.push(i);
78 }
79 _scriptMap.wait_write.reverse();
80 _writeScript();
81 };
82 _writeScript = function(){
83 //写入我们的JS 了。
84 var head = document.getElementsByTagName("head").item(0),len = _scriptMap.wait_write.length;
85 for (var i;_scriptMap.wait_write.length&&(i=_scriptMap.wait_write.shift());) {
86 var script = document.createElement("script"),
87 url = i || "";
88 script.setAttribute("async",true);//高级浏览器支持HTML5特性
89 script.setAttribute("type","text/javascript");
90 script.setAttribute("src",url);
91 head.appendChild(script);
92 _scriptMap.writted[url] = true;//这里无所谓,只要有这个URL就可以
93 };
94 };
95 alfred.extend = function(){
96 var deep = false,
97 len,
98 options, name, src, copy, copyIsArray, clone,
99 target = arguments[0] || {},
100 i = 1;
101 len = arguments.length;
102 if (!len)
103 {
104 return this;
105 }
106 if(alfred.isBoolean(target))
107 {
108 deep = arguments[0];
109 to = arguments[1];
110 i = 2;
111 }
112 if (!(alfred.isObject(target) || alfred.isFunction(target))) {
113 target = {};
114 }
115 if (len = i)
116 {
117 target = this;
118 --i;
119 }
120 for (;i<len;i++) {
121 if ((options=arguments[i])!==null)
122 {
123 for (name in options) {
124 copy = options[name];
125 src = target[name];
126 if(src){throw "Becareful : you are rewrite the "+_handle+"."+name+"!"}
127 if (copy===target) {continue}
128 if (deep && copy && (alfred.isObject(copy) || (copyIsArray = alfred.isArray(copy))))
129 {
130 if (copyIsArray)
131 {
132 copyIsArray = false;
133 clone = src && alfred.isArray(src) ? src : [];
134 }
135 else
136 {
137 clone = src && alfred.isObject(src) ? src : [];
138 }
139 target[ name ] = alfred.extend( deep, clone, copy );
140 }
141 else if ( copy !== undefined )
142 {
143 target[name] = copy;
144 }
145 }
146 }
147 }
148 };
149 alfred.isNumber = function(it){return _is(it,/^\[object number\]$/)};
150 alfred.isString = function(it){return _is(it,/^\[object string\]$/)};
151 alfred.isFunction = function(it){return _is(it,/^\[object function\]$/)};
152 alfred.isObject = function(it){return _is(it,/^\[object object\]$/)};
153 alfred.isArray = function(it){return _is(it,/^\[object array\]$/)};
154 alfred.isBoolean = function(it){return typeof it ==='boolean'};
155 alfred.isDom = function(it){return _is(it,/^\[object html\w+\]$/)};
156
157 alfred.extend({
158 author : "alfred",
159 version : 1.01,
160 global : window,
161 doc : window.document,
162 reset : function(it){alfred.global[it]=alfred;},
163 log : function()
164 {
165 if(window.console && console.log)
166 {
167 return console.log.apply(window,arguments)
168 }
169 },
170 error : function(name,value)
171 {
172 throw {"name":name,"message":value};
173 },
174 require : function(method)
175 {
176 var m2u = _scriptMap.method_url,
177 u2m = _scriptMap.url_method,
178 r;
179 if(!(m2u[method])){throw "Error : you need setMethod first"}
180 if (!_scriptMap.visited[m2u[method][0]] && !_scriptMap.writted[m2u[method][0]]) {
181 //haven't be visited or write
182 _scriptMap.visited[m2u[method][0]] = true;
183 //use an beautiful code in here
184 for(; m2u[method][1].length &&(r=m2u[method][1].shift());)
185 {
186 require(r);
187 }
188 _listUrl();
189 }
190 },
191 setMethod : function(url,method,rely)
192 {
193 var i, method = alfred.isArray(method)? method:[method],
194 rely = alfred.isArray(rely)?rely:[rely];
195 if (url && !_scriptMap.url_method[url]){
196 _scriptMap.url_method[url] = method;
197 for (;method.length&&(i=method.shift());) {
198 _scriptMap.method_url[i] = {"0" : url, "1" : rely};
199 }
200 return this;
201 }
202 throw "Error : you are setMethod in an old method";
203 },
204 ready : function(){
205 _checkReady.apply(window,arguments);
206 },
207 each : function(arg,callback){
208 for(var i in arg){
209 if(arg[i])
210 {
211 callback.call(arg[i],i);
212 }
213 }
214 return arg;
215 }
216 });
217 window.alfred = alfred;
218 })(window)
1 alfred.setMethod("basic.js",["alfred","alfred.global","alfred.doc","alfred.reset","alfred.log","alfred.isNumber","alfred.isFunction","alfred.isArray","alfred.isObject","alfred.isString","alfred.isBoolean","alfred.require","alfred.setMethod","alfred.extend"],[]);
这样设置了以后就可以告诉下面的JS 我已经提供了这些方法。随意alfred.require("alfred.reset"); 就可以把文件拉进页面注册好。
页面内是这样的。
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>
5 </title>
6 </head>
7 <body>
8 <script type="text/javascript" src="base.js"></script>
9 <script type="text/javascript" src="deps.js"></script>
10 <script type="text/javascript">
11 alfred.reset("$");
12
13 $.require("alfred.dom");
14
15 $(function(){
16 var a = $.dom("<div id='test' style='width:200px;height:200px;background:red;'> adf</div>");
17 $.dom("body").prepend(a);
18 })
19 </script>
20 </body>
21 </html>
alfred.reset 是为了方便自己设置方法名字。这样我们几乎可以象jquery一样使用了。
alfred.reset("$");
$.require("alfred.dom");
$.dom("div a span:first-child").append("hello alfred");
就 可以这样用了。。
如果感觉这样不爽。欢迎各位朋友来交流下。我刚学JS 不是很久。所以技艺不高,研究不深。忘各位来指点下。互相提高。QQ:164864042
-------无代码 ,生活不完美。