Ajax组件(wagang版)之无依赖化
前文讲到Ajax的功能与代码,本文补叙一下Ajax的无依赖化。
基本的ajax.js与业务逻辑无关,它是基于QWrap开发的。但是,QWrap好像是个不知名的框架,对于不用QWrap框架的公司来说,没必要为了用这个js而引入一个所谓的QWrap框架。
没问题,我们可以依赖QWrap开发Ajax,而发布出一个无依赖的Ajax。
ajax.js的最前面有一段代码:
它是一段适配代码。----QWrap提供一系列静态方法,在开发组件时用这些静态方法,发布时可以抽取出来。
QWrap提供了一个代码抽取的简易工具(js版的):
http://dev.qwrap.com/resource/js/_tools/combojsfiles/_examples/Solo.html
将适配代码粘贴到该页面的“硬性代码”框中,点击“依赖抽取”按钮。
会依次弹出以下几个框:
1。分析硬性代码,解析出依赖为:{"ObjectH":{"mix":{},"encodeURIJson":{}},"NodeH":{"encodeURIForm":{}},"CustEvent":{}}
2。依赖这个不可细折的模块// document.write('<script type="text/javascript" src="' + srcPath + 'core/custevent.js"><\/script>');
3。所有的直接或间接依赖:{"ObjectH":{"mix":{},"encodeURIJson":{},"isWrap":{},"isArray":{}},"NodeH":{"encodeURIForm":{}},"CustEvent":{"prototype":{},"createEvents":{}},"DomU":{"create":{}},"ArrayH":{"indexOf":{}},"error":{},"HelperH":{"methodize":{}},"CustEventTargetH":{"createEvents":{}},"CustEventTarget":{"prototype":{}},"FunctionH":{"methodize":{}}}
之后会将抽取将果显示在下面的“结果”文本框里。
尽管比QWrap整个库来说,代码已经少了很多,但是,代码还是有点多。
最主要的原因如第二个弹框所言:依赖这个不可细折的模块:custevent.js。
CustEvent是参考dom标准事件实现的一套用户自定义事件的组件。由于会在大量组件中用到,所以放在了QWrap的核心库。它拥有强大的多头事件功能,不过,在实际中,Ajax支持独占事件就差不多够用了,在对Ajax进行无依赖化时,可以考虑把它简化成一个只支持单头事件的简单功能。按Ajax的需求,适配代码可以简化成如下:
再把这段适配代码当作硬性代码来抽取一次,抽取结果就变成这样的了:
去掉后再点击“修改结果后再次抽取”就得到了以下代码:
是的,它就是Ajax的适配代码对QWrap的依赖了。
当然,mix还可以简化,那就是纯手工可以完成的事了,略过不提…………………………
附:QWrap网址:http://www.qwrap.com
基本的ajax.js与业务逻辑无关,它是基于QWrap开发的。但是,QWrap好像是个不知名的框架,对于不用QWrap框架的公司来说,没必要为了用这个js而引入一个所谓的QWrap框架。
没问题,我们可以依赖QWrap开发Ajax,而发布出一个无依赖的Ajax。
ajax.js的最前面有一段代码:
var mix=QW.ObjectH.mix,
encodeURIJson=QW.ObjectH.encodeURIJson,
encodeURIForm=QW.NodeH.encodeURIForm,
CustEvent=QW.CustEvent;
QWrap提供了一个代码抽取的简易工具(js版的):
http://dev.qwrap.com/resource/js/_tools/combojsfiles/_examples/Solo.html
将适配代码粘贴到该页面的“硬性代码”框中,点击“依赖抽取”按钮。
会依次弹出以下几个框:
1。分析硬性代码,解析出依赖为:{"ObjectH":{"mix":{},"encodeURIJson":{}},"NodeH":{"encodeURIForm":{}},"CustEvent":{}}
2。依赖这个不可细折的模块// document.write('<script type="text/javascript" src="' + srcPath + 'core/custevent.js"><\/script>');
3。所有的直接或间接依赖:{"ObjectH":{"mix":{},"encodeURIJson":{},"isWrap":{},"isArray":{}},"NodeH":{"encodeURIForm":{}},"CustEvent":{"prototype":{},"createEvents":{}},"DomU":{"create":{}},"ArrayH":{"indexOf":{}},"error":{},"HelperH":{"methodize":{}},"CustEventTargetH":{"createEvents":{}},"CustEventTarget":{"prototype":{}},"FunctionH":{"methodize":{}}}
之后会将抽取将果显示在下面的“结果”文本框里。
尽管比QWrap整个库来说,代码已经少了很多,但是,代码还是有点多。
最主要的原因如第二个弹框所言:依赖这个不可细折的模块:custevent.js。
CustEvent是参考dom标准事件实现的一套用户自定义事件的组件。由于会在大量组件中用到,所以放在了QWrap的核心库。它拥有强大的多头事件功能,不过,在实际中,Ajax支持独占事件就差不多够用了,在对Ajax进行无依赖化时,可以考虑把它简化成一个只支持单头事件的简单功能。按Ajax的需求,适配代码可以简化成如下:
var mix=QW.ObjectH.mix,
encodeURIJson=QW.ObjectH.encodeURIJson,
encodeURIForm=QW.NodeH.encodeURIForm,
CustEvent={
createEvents: function(obj){
obj.fire = function (sEvent) {
var key = 'on' + sEvent;
return this[key] && this[key]();
}
}
};
再把这段适配代码当作硬性代码来抽取一次,抽取结果就变成这样的了:
View Code
其中encodeURIForm里有一句“el=g(el);”,这个是为了兼容id字符串变成html元素,可以去掉本句。// document.write('<script type="text/javascript" src="' + srcPath + 'core/core_base.js"><\/script>');
(function() {
var QW = {
};
window.QW = QW;
}());
// document.write('<script type="text/javascript" src="' + srcPath + 'core/object.h.js"><\/script>');
(function() {
function getConstructorName(o) {
return o != null && Object.prototype.toString.call(o).slice(8, -1);
}
var ObjectH = {
isArray: function(obj) {
return getConstructorName(obj) == 'Array';
},
isWrap: function(obj, coreName) {
return !!(obj && obj[coreName || 'core']);
},
mix: function(des, src, override) {
if (ObjectH.isArray(src)) {
for (var i = 0, len = src.length; i < len; i++) {
ObjectH.mix(des, src[i], override);
}
return des;
}
for (i in src) {
if (override || !(des[i] || (i in des))) {
des[i] = src[i];
}
}
return des;
},
encodeURIJson: function(json){
var s = [];
for( var p in json ){
if(json[p]==null) continue;
if(json[p] instanceof Array)
{
for (var i=0;i<json[p].length;i++) s.push( encodeURIComponent(p) + '=' + encodeURIComponent(json[p][i]));
}
else
s.push( encodeURIComponent(p) + '=' + encodeURIComponent(json[p]));
}
return s.join('&');
}
};
QW.ObjectH = ObjectH;
}());
// document.write('<script type="text/javascript" src="' + srcPath + 'dom/dom.u.js"><\/script>');
(function() {
var DomU = {
create: (function() {
var temp = document.createElement('div'),
wrap = {
option: [ 1, "<select multiple='multiple'>", "</select>" ],
optgroup: [ 1, "<select multiple='multiple'>", "</select>" ],
legend: [ 1, "<fieldset>", "</fieldset>" ],
thead: [ 1, "<table>", "</table>" ],
tbody: [ 1,"<table>", "</table>" ],
tfoot : [1,"<table>", "</table>"],
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
th: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
_default: [ 0, "", "" ]
},
tagName = /<(\w+)/i;
return function(html, rfrag, doc) {
var dtemp = (doc && doc.createElement('div')) || temp,
root = dtemp,
tag = ( tagName.exec( html ) || ["",""] )[1],
wr = wrap[ tag ] || wrap[ '_default' ],
dep = wr[0];
dtemp.innerHTML = wr[1] + html + wr[2];
while( dep-- ) {
dtemp = dtemp.firstChild;
}
var el = dtemp.firstChild;
if (!el || !rfrag) {
while (root.firstChild) {
root.removeChild(root.firstChild);
}
//root.innerHTML = '';
return el;
} else {
doc = doc || document;
var frag = doc.createDocumentFragment();
while (el = dtemp.firstChild) {
frag.appendChild(el);
}
return frag;
}
};
}())
};
QW.DomU = DomU;
}());
// document.write('<script type="text/javascript" src="' + srcPath + 'dom/node.h.js"><\/script>');
(function() {
var ObjectH = QW.ObjectH,
DomU = QW.DomU;
var g = function(el, doc) {
if ('string' == typeof el) {
if (el.indexOf('<') == 0) {return DomU.create(el, false, doc); }
return (doc || document).getElementById(el);
} else {
return (ObjectH.isWrap(el)) ? arguments.callee(el.core) : el;
}
};
var NodeH = {
encodeURIForm: function(el, filter) {
el = g(el);
filter = filter || function(el) {return false; };
var result = [],
els = el.elements,
l = els.length,
i = 0,
push = function(name, value) {
result.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
};
for (; i < l; ++i) {
el = els[i];
var name = el.name;
if (el.disabled || !name || filter(el)) {continue; }
switch (el.type) {
case "text":
case "hidden":
case "password":
case "textarea":
push(name, el.value);
break;
case "radio":
case "checkbox":
if (el.checked) {push(name, el.value); }
break;
case "select-one":
if (el.selectedIndex > -1) {push(name, el.value); }
break;
case "select-multiple":
var opts = el.options;
for (var j = 0; j < opts.length; ++j) {
if (opts[j].selected) {push(name, opts[j].value); }
}
break;
}
}
return result.join("&");
}
};
QW.NodeH = NodeH;
}());
去掉后再点击“修改结果后再次抽取”就得到了以下代码:
// document.write('<script type="text/javascript" src="' + srcPath + 'core/core_base.js"><\/script>');
(function() {
var QW = {
};
window.QW = QW;
}());
// document.write('<script type="text/javascript" src="' + srcPath + 'core/object.h.js"><\/script>');
(function() {
function getConstructorName(o) {
return o != null && Object.prototype.toString.call(o).slice(8, -1);
}
var ObjectH = {
isArray: function(obj) {
return getConstructorName(obj) == 'Array';
},
mix: function(des, src, override) {
if (ObjectH.isArray(src)) {
for (var i = 0, len = src.length; i < len; i++) {
ObjectH.mix(des, src[i], override);
}
return des;
}
for (i in src) {
if (override || !(des[i] || (i in des))) {
des[i] = src[i];
}
}
return des;
},
encodeURIJson: function(json){
var s = [];
for( var p in json ){
if(json[p]==null) continue;
if(json[p] instanceof Array)
{
for (var i=0;i<json[p].length;i++) s.push( encodeURIComponent(p) + '=' + encodeURIComponent(json[p][i]));
}
else
s.push( encodeURIComponent(p) + '=' + encodeURIComponent(json[p]));
}
return s.join('&');
}
};
QW.ObjectH = ObjectH;
}());
// document.write('<script type="text/javascript" src="' + srcPath + 'dom/node.h.js"><\/script>');
(function() {
var NodeH = {
encodeURIForm: function(el, filter) {
filter = filter || function(el) {return false; };
var result = [],
els = el.elements,
l = els.length,
i = 0,
push = function(name, value) {
result.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
};
for (; i < l; ++i) {
el = els[i];
var name = el.name;
if (el.disabled || !name || filter(el)) {continue; }
switch (el.type) {
case "text":
case "hidden":
case "password":
case "textarea":
push(name, el.value);
break;
case "radio":
case "checkbox":
if (el.checked) {push(name, el.value); }
break;
case "select-one":
if (el.selectedIndex > -1) {push(name, el.value); }
break;
case "select-multiple":
var opts = el.options;
for (var j = 0; j < opts.length; ++j) {
if (opts[j].selected) {push(name, opts[j].value); }
}
break;
}
}
return result.join("&");
}
};
QW.NodeH = NodeH;
}());
是的,它就是Ajax的适配代码对QWrap的依赖了。
当然,mix还可以简化,那就是纯手工可以完成的事了,略过不提…………………………
附:QWrap网址:http://www.qwrap.com