放羊测试测完了再测这两个瞎搞的下拉列表组建 看看从单元测试模块化的角度组建会写成啥样
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}
})()
})