放羊测试测完了再测这两个瞎搞的下拉列表组建 看看从单元测试模块化的角度组建会写成啥样
1:ajax请求 简单文本
2:1个页面多个实例
3:复杂展示+自定义点击+自定义处理函数
4:延迟请求
5 插件封装 jq和reqjs
6:jsonp 支持(还未实现)
jq
/** * Created by qqloving on 14-3-24. */ (function($) { $.fn.xiala = function(ops) { var url=ops.url||''; var clickfn=ops.clickfn||null; console.log(this); //this.selector //this.length; var objla= { pop_len: 10, pop_cn: 'autoDis', hover_cn: 'cur', TargetElement:null, InstancesNum:0, ajaxurl:'', ajaxdatafn:function(){}, sourcelist:[], clicklist:[], time:null, init:function(Element){ this.setDom(); if(Element.getAttribute('type')!='text'||Element.nodeName!='INPUT') { return this; } this.TargetElement=Element; return this }, bind :function(url,datafn){ var self=this; var Element=self.TargetElement; self.ajaxurl=url; self.ajaxdatafn=datafn; Element.onkeyup=function(e){ //还有回车没有处理 e=e||window.event; var lis=self.pop.getElementsByTagName('li'), lens=lis.length, n=lens, temp; if(e.keyCode==38){ for (var i = 0; i < lens; i++) { //遍历结果数据,判断是否被选中 if (lis[i].className) { temp = i; } else { n--; } } if (n == 0) { //如果没有被选中的li元素,则选中最后一个 lis[lens - 1].className = self.hover_cn; this.value = lis[lens - 1].innerHTML; } else { //如果有被选中的元素,则选择上一个元素并赋值给input if (lis[temp] == lis[0]) { //如果选中的元素是第一个孩子节点则跳到最后一个选中 lis[lens - 1].className = self.hover_cn; this.value = lis[lens - 1].innerHTML; lis[temp].className = ''; } else { lis[temp - 1].className = self.hover_cn; this.value = lis[temp - 1].innerHTML; lis[temp].className = ''; } } }else if(e.keyCode==40){ for (var i = 0; i < lens; i++) { //遍历结果数据,判断是否被选中 if (lis[i].className) { temp = i; } else { n--; } } if (n == 0) { lis[0].className = self.hover_cn; this.value = lis[0].innerHTML; } else { if (lis[temp] == lis[lens - 1]) { lis[0].className = self.hover_cn; this.value = lis[0].innerHTML; lis[temp].className = ''; } else { lis[temp + 1].className = self.hover_cn; this.value = lis[temp + 1].innerHTML; lis[temp].className = ''; } } } else{ //如果弹出层没有显示则执行插入操作,并显示弹出层 self.insert(this); } }; Element.onblur=function(e){ setTimeout(function() { self.pop.style.display = 'none'; }, 300); } return self; }, setDom:function(){ var self=this, dom=document.createElement('div') iframe=document.createElement('iframe'), ul=document.createElement('ul'); document.body.appendChild(dom); iframe.setAttribute('frameborder',0); iframe.setAttribute('scrolling', 'no') iframe.style.cssText='z-index:-1;position:absolute;left:0;top:0;' dom.className=self.pop_cn; dom.appendChild(iframe); dom.appendChild(ul); dom.onmouseover=function(e){ e=e||window.event; var target= e.srcElement|| e.target; if(target.tagName=='LI'){ for(var i= 0,lis=self.pop.getElementsByTagName('li');i<lis.length;i++){ lis[i].className='' } target.className=self.hover_cn; } }; dom.onmouseout=function(e){ e=e||window.event; var target= e.srcElement|| e.target; if (target.tagName == 'LI') target.className = ''; } dom.onclick=function(e){ //还得做个事件处理列表 e=e||window.event; var target= e.srcElement|| e.target; if(self.clicklist.length==0) { if (target.tagName == 'LI') { self.value = target.innerHTML; } } else { var own=null; for(var i= 0,j=self.clicklist.length;i<j;i++){ own=self.clicklist[i](target) if(own) { self.value = own; } } } self.TargetElement.value=self.value; self.pop.style.display='none' } self.pop=dom; }, insert:function(self){ var bak = [], s, li = [], left = 0, top = 0, val = self.value; left=self.getBoundingClientRect().left+document.documentElement.scrollLeft; top=self.getBoundingClientRect().top+document.documentElement.scrollTop+self.offsetHeight; this.pop.style.cssText= 'width:' + self.offsetWidth + 'px;' + 'position:absolute;left:' + left + 'px;top:' + top + 'px;display:none;'; this.pop.getElementsByTagName('iframe')[0].setAttribute('width',self.offsetWidth ); this.pop.getElementsByTagName('iframe')[0].setAttribute('height',self.offsetHeight); this.pop.getElementsByTagName('ul')[0].innerHTML='<li>请稍后</li>'; this.pop.style.display='block'; var that=this; function getajax(){ that.ajax.request(that.ajaxurl,{ success:function(xhr){ console.log('= ='); // console.log(xhr.responseText); that.sourcelist=that.ajaxdatafn(xhr.responseText); li=[]; s = that.sourcelist.length > that.pop_len ? that.pop_len: that.sourcelist.length; for(var i= 0;i<s;i++){ li.push('<li>' + that.sourcelist[i].__syshtml + '</li>') } that.pop.getElementsByTagName('ul')[0].innerHTML=li.join('') //console.log(that.ajaxdatafn(xhr.responseText)); left=self.getBoundingClientRect().left+document.documentElement.scrollLeft; top=self.getBoundingClientRect().top+document.documentElement.scrollTop+self.offsetHeight; that.pop.style.cssText= 'width:' + self.offsetWidth + 'px;' + 'position:absolute;left:' + left + 'px;top:' + top + 'px'; that.pop.getElementsByTagName('iframe')[0].setAttribute('width',self.offsetWidth ); that.pop.getElementsByTagName('iframe')[0].setAttribute('height',self.offsetHeight); } }) } clearTimeout(that.time); that.time= setTimeout(getajax(),1000); }, addclick:function(fn){ this.clicklist.push(fn); return this; }, ajax:(function (){ function request (url,opt){ function createXHR(){ if(typeof XMLHttpRequest != "undefined"){ createXHR = function(){ return new XMLHttpRequest(); }; }else if(typeof ActiveXObject != "undefined"){ createXHR = function(){ if(typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"]; for(var i = 0, len = versions.length; i < len; i++){ try{ var xhr = new ActiveXObject(version[i]); arguments.callee.activeXString = version[i]; return xhr; }catch(ex){ //skip } } } return new ActiveXObject(arguments.callee.activeXString); }; }else{ createXHR = function(){ throw new Error("No XHR Object available."); }; } return createXHR(); } function fn(){} var async=opt.async!==false, method=opt.method||"Get", data=opt.data||null, success=opt.success||fn, failure=opt.failure||fn; method=method.toLocaleLowerCase(); if(method=="get"&&data){ url+=(url.indexOf('?')==-1?'?':'&')+data; } var xhr=createXHR(); xhr.onreadystatechange=function(){ _onStateChange(xhr,success,failure); } if(method=="post"){ xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;'); } xhr.open(method,url,async); xhr.send(data); return xhr; } function _onStateChange(xhr,success,failure){ if(xhr.readyState == 4){ var s = xhr.status; if(s>= 200 && s < 300){ success(xhr); }else{ failure(xhr); } }else{} } return {request:request} })() }; return objla.init(this[0]).bind(url,clickfn); }; })(jQuery);
简单实例
({ pop_len: 10, pop_cn: 'autoDis', hover_cn: 'cur', TargetElement:null, InstancesNum:0, ajaxurl:'', ajaxdatafn:function(){}, sourcelist:[], clicklist:[], time:null, init:function(){ this.setDom(); return this }, bind :function(Element,url,datafn){ if(Element.getAttribute('type')!='text'||Element.nodeName!='INPUT') { return null; } var self=this; self.ajaxurl=url; self.ajaxdatafn=datafn; self.TargetElement=Element; Element.onkeyup=function(e){ //还有回车没有处理 e=e||window.event; var lis=self.pop.getElementsByTagName('li'), lens=lis.length, n=lens, temp; if(e.keyCode==38){ for (var i = 0; i < lens; i++) { //遍历结果数据,判断是否被选中 if (lis[i].className) { temp = i; } else { n--; } } if (n == 0) { //如果没有被选中的li元素,则选中最后一个 lis[lens - 1].className = self.hover_cn; this.value = lis[lens - 1].innerHTML; } else { //如果有被选中的元素,则选择上一个元素并赋值给input if (lis[temp] == lis[0]) { //如果选中的元素是第一个孩子节点则跳到最后一个选中 lis[lens - 1].className = self.hover_cn; this.value = lis[lens - 1].innerHTML; lis[temp].className = ''; } else { lis[temp - 1].className = self.hover_cn; this.value = lis[temp - 1].innerHTML; lis[temp].className = ''; } } }else if(e.keyCode==40){ for (var i = 0; i < lens; i++) { //遍历结果数据,判断是否被选中 if (lis[i].className) { temp = i; } else { n--; } } if (n == 0) { lis[0].className = self.hover_cn; this.value = lis[0].innerHTML; } else { if (lis[temp] == lis[lens - 1]) { lis[0].className = self.hover_cn; this.value = lis[0].innerHTML; lis[temp].className = ''; } else { lis[temp + 1].className = self.hover_cn; this.value = lis[temp + 1].innerHTML; lis[temp].className = ''; } } } else{ //如果弹出层没有显示则执行插入操作,并显示弹出层 self.insert(this); } }; Element.onblur=function(e){ setTimeout(function() { self.pop.style.display = 'none'; }, 300); } return self; }, setDom:function(){ var self=this, dom=document.createElement('div') iframe=document.createElement('iframe'), ul=document.createElement('ul'); document.body.appendChild(dom); iframe.setAttribute('frameborder',0); iframe.setAttribute('scrolling', 'no') iframe.style.cssText='z-index:-1;position:absolute;left:0;top:0;' dom.className=self.pop_cn; dom.appendChild(iframe); dom.appendChild(ul); dom.onmouseover=function(e){ e=e||window.event; var target= e.srcElement|| e.target; if(target.tagName=='LI'){ for(var i= 0,lis=self.pop.getElementsByTagName('li');i<lis.length;i++){ lis[i].className='' } target.className=self.hover_cn; } }; dom.onmouseout=function(e){ e=e||window.event; var target= e.srcElement|| e.target; if (target.tagName == 'LI') target.className = ''; } dom.onclick=function(e){ //还得做个事件处理列表 e=e||window.event; var target= e.srcElement|| e.target; if(self.clicklist.length==0) { if (target.tagName == 'LI') { self.value = target.innerHTML; } } else { var own=null; for(var i= 0,j=self.clicklist.length;i<j;i++){ own=self.clicklist[i](target) if(own) { self.value = own; } } } self.TargetElement.value=self.value; self.pop.style.display='none' } self.pop=dom; }, insert:function(self){ var bak = [], s, li = [], left = 0, top = 0, val = self.value; left=self.getBoundingClientRect().left+document.documentElement.scrollLeft; top=self.getBoundingClientRect().top+document.documentElement.scrollTop+self.offsetHeight; this.pop.style.cssText= 'width:' + self.offsetWidth + 'px;' + 'position:absolute;left:' + left + 'px;top:' + top + 'px;display:none;'; this.pop.getElementsByTagName('iframe')[0].setAttribute('width',self.offsetWidth ); this.pop.getElementsByTagName('iframe')[0].setAttribute('height',self.offsetHeight); this.pop.getElementsByTagName('ul')[0].innerHTML='<li>请稍后</li>'; this.pop.style.display='block'; var that=this; function getajax(){ that.ajax.request(that.ajaxurl,{ success:function(xhr){ console.log('= ='); // console.log(xhr.responseText); that.sourcelist=that.ajaxdatafn(xhr.responseText); li=[]; s = that.sourcelist.length > that.pop_len ? that.pop_len: that.sourcelist.length; for(var i= 0;i<s;i++){ li.push('<li>' + that.sourcelist[i].__syshtml + '</li>') } that.pop.getElementsByTagName('ul')[0].innerHTML=li.join('') //console.log(that.ajaxdatafn(xhr.responseText)); left=self.getBoundingClientRect().left+document.documentElement.scrollLeft; top=self.getBoundingClientRect().top+document.documentElement.scrollTop+self.offsetHeight; that.pop.style.cssText= 'width:' + self.offsetWidth + 'px;' + 'position:absolute;left:' + left + 'px;top:' + top + 'px'; that.pop.getElementsByTagName('iframe')[0].setAttribute('width',self.offsetWidth ); that.pop.getElementsByTagName('iframe')[0].setAttribute('height',self.offsetHeight); } }) } clearTimeout(that.time); that.time= setTimeout(getajax(),1000); }, addclick:function(fn){ this.clicklist.push(fn); return this; }, ajax:(function (){ function request (url,opt){ function createXHR(){ if(typeof XMLHttpRequest != "undefined"){ createXHR = function(){ return new XMLHttpRequest(); }; }else if(typeof ActiveXObject != "undefined"){ createXHR = function(){ if(typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"]; for(var i = 0, len = versions.length; i < len; i++){ try{ var xhr = new ActiveXObject(version[i]); arguments.callee.activeXString = version[i]; return xhr; }catch(ex){ //skip } } } return new ActiveXObject(arguments.callee.activeXString); }; }else{ createXHR = function(){ throw new Error("No XHR Object available."); }; } return createXHR(); } function fn(){} var async=opt.async!==false, method=opt.method||"Get", data=opt.data||null, success=opt.success||fn, failure=opt.failure||fn; method=method.toLocaleLowerCase(); if(method=="get"&&data){ url+=(url.indexOf('?')==-1?'?':'&')+data; } var xhr=createXHR(); xhr.onreadystatechange=function(){ _onStateChange(xhr,success,failure); } if(method=="post"){ xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;'); } xhr.open(method,url,async); xhr.send(data); return xhr; } function _onStateChange(xhr,success,failure){ if(xhr.readyState == 4){ var s = xhr.status; if(s>= 200 && s < 300){ success(xhr); }else{ failure(xhr); } }else{} } return {request:request} })() })test