无依赖的combobox组件(autocomplete组件)


wagang.net的首页需要一个combobox组件(autocomplete)。
QWrap里有一个:http://dev.qwrap.com/resource/js/wagang/combobox/_examples/ComboBox-Demo.html
不过这组件开发时是依赖QWrap的。可是我只想引用一个组件,而不想附带的引入一个qwrap库。
好在QWrap堆砌库时采用了Helper规范,很多方法都是静态方法,可以独立到方法这个粒度。
所以,可以订制一个无依赖的combobox组件,以使其代码量昼量少,从而节约网络流量,提高用户体验。
OK,那就开始一次无依赖化之旅吧。

QWrap建议组件开发者使用静态方法,并且将对外引用的静态方法,统一定义在组件闭包的最前面。这一代码码,就集中体现它对QWrap的依赖。
这代码码同时也相当于一段适配代码。如果想换成依赖别一个库的,只需要将这段代码适配成其它库即可。

combobox的全部代码在这里可以看到:http://dev.qwrap.com/resource/js/wagang/combobox/combobox.js
其中适配代码即这段:
View Code
var mix=QW.ObjectH.mix,
DomU
=QW.DomU,
createElement
=DomU.createElement,
EventH
=QW.EventH,
target
=EventH.getTarget,
keyCode
=EventH.getKeyCode,
preventDefault
=EventH.preventDefault,
CustEvent
=QW.CustEvent,
NodeH
=QW.NodeH,
addClass
=NodeH.addClass,
removeClass
=NodeH.removeClass,
setStyle
=NodeH.setStyle,
getXY
=NodeH.getXY,
ancestorNode
=NodeH.ancestorNode,
on
=QW.EventTargetH.addEventListener,
isIe
=(/msie/i).test(navigator.userAgent);


观察以上代码,可以看到,除了CustEvent这个是依赖整个模块,而不是精确到方法级别,其它的都是精确到方法级别。

CustEvent是自定义事件,该模块的js(http://dev.qwrap.com/resource/js/core/custevent.h.js),YUI压缩后约1.5K。不算大。
不过,这1.5K也可以省下来。
因为wagang.net首页所需的自定义事件,不需要多头。支持onxxx=function(){}就足够用了。

另外,getXY这个方法,由于浏览器兼容的代码太多,有好几百字节。也可以把绝对定位,改成调整dom结构的方式来定位,以节约代码。
所以,solo后的适配代码就变成这样的了:
View Code
var mix=function(des, src){
for(var i in src){
des[i]
= src[i];
}
},
//DomU=QW.DomU,
createElement=function (tagName, property) {
var el = document.createElement(tagName);
if (property) {
for (var i in property) el[i] = property[i];
}
return el;
},
//EventH=QW.EventH,
target=function(e) {
e
=e||window.event;
return e.target || e.srcElement;
},
keyCode
=function(e) {
e
=e||window.event;
return e.which || e.keyCode || e.charCode;
},
preventDefault
=function(e) {
e
=e||window.event;
e.preventDefault
&& e.preventDefault() || (e.returnValue = false);
},
//CustEvent=QW.CustEvent,
//NodeH=QW.NodeH,
hasClass=function(el, cn) {
return new RegExp('(?:^|\\s)' +cn+ '(?:\\s|$)','i').test(el.className);
},
addClass
=function (el, cn) {
if (!hasClass(el, cn)) {
el.className
= (el.className + ' '+cn).replace(/^\s+|\s+$/g,"");
}
},
removeClass
=function (el, cn) {
if (hasClass(el, cn)) {
el.className
= el.className.replace(new RegExp('(?:\\s|^)' +cn+ '(?:\\s|$)','i'),' ').replace(/^\s+|\s+$/g,"");
}
},
//setStyle=NodeH.setStyle,
//getXY=NodeH.getXY, 由于getXY的兼容代码很长,所以无依赖化时,稍稍调整下,不用位置,而改用dom结构来定位
ancestorNode=function(el,tagName){
while(el=el.parentNode){
if(el.tagName==tagName) return el;
}
return null;
},
on
=function (element, name, handler) {
element.addEventListener
&& element.addEventListener(name, handler, false)
|| element.attachEvent && element.attachEvent('on' + name, handler);
},
isIe
=(/msie/i).test(navigator.userAgent);


全部代码如下:
http://dev.qwrap.com/resource/js/wagang/combobox/_examples/ComboBox-WaGang.net.html

solo出的combobox.js部分,代码yui压后只有4.7K,足够满足要求了。

以上,只是大略记述QWrap组件无依赖化的过程。
由于QWrap框架用helper规范来堆砌库,所以基于helper开发出来的组件也很容易改装成无依赖的组件。
这也是QWrap的初衷之一:服务于组件开发者,让他们依赖QWrap开发组件,而发布出无依赖的组件

附:
以上代码中,所说到的combobox组件,来自:http://dev.qwrap.com/resource/js/wagang/combobox/_examples/ComboBox-Demo.html
独立后的combobox组件,应用于wagang.net主页:http://www.wagang.net
更多wagang组件,参见:http://dev.qwrap.com/resource/js/wagang/_index.html







原文地址:https://www.cnblogs.com/jkisjk/p/combobox_solo.html