因为项目需要,写了一个简单的AJAX自动完成的小例子,这里给出代码。
代码没有优化,优化方向是:1.进一步解耦 2.增加本地数据缓存的筛选,减少交互次数 3.优化筛选算法
有兴趣的朋友可以去尝试一下。
/*
 *    AutoComplete Class
 *  Author: Robin Chen(robchen@126.com)
*/

//AutoComplete Class
var AutoComplete = function(dom,options){
    this.dom = dom;
    this.startPoint = options.startPoint || 3;
    this.JSONService = options.JSONService;
    this.selector = new AutoCompleteSelector(this);
    var __this = this;
    this.selectMode = true;
    this.dom.onfocus = this.dom.onchange = this.dom.onkeyup = function(){
        setTimeout(function(){
            if(__this.dom.cacheValue != __this.dom.value){
                __this.dom.cacheValue = __this.dom.value;
                __this.search();
            }else{
                if(__this.dom.value.length >= __this.startPoint)__this.selector.show();    
            }
        },10);
    }
    var onMouseClick = function(evt){
        var evt = evt || event;
        var target = evt.target || evt.srcElement;
        if(target != __this.dom && target != __this.selector.dom){
            __this.selector.hide();
        }
    }
    try{
        document.body.attachEvent('onclick',onMouseClick);
    }catch(e){
        document.body.addEventListener('click',onMouseClick,false);    
    }
}

AutoComplete.prototype = {
    request:null,
    dataCache:null,
    createXMLHttpRequest:function(){
        try{
            return new XMLHttpRequest();    
        }catch(e){
            return new ActiveXObject('Microsoft.XMLHTTP');    
        }
    },
    search:function(){
        var keyword = this.dom.value;
        if(keyword.length < this.startPoint)return;
        if(this.request)this.request.abort();
        var request = this.request = this.createXMLHttpRequest();
        request.open('GET',this.JSONService + '?keyword=' + escape(keyword),true);
        var __this = this;
        request.onreadystatechange = function(){
            if(request.readyState == 4 && request.status == 200){
                var data = eval('(' + request.responseText + ')');
                __this.parseData.call(__this,data);
            }
        }
        request.send();
    },
    parseData:function(data){
        this.dataCache = data;
        this.selector.load(data);
        if(this.selector.dom.getElementsByTagName('div').length > 0){
            this.selector.show();
        }else{
            this.selector.hide();    
        }
    }
}

//AutoCompleteSelector Class
var AutoCompleteSelector = function(autoCompleteObject){
    this.autoCompleteObject = autoCompleteObject;
    if(arguments[1]){
        this.dom = arguments[1];
    }else{
        this.dom = this.createDefaultSelectorElement();    
    }
}

AutoCompleteSelector.prototype = {
    createDefaultSelectorElement:function(){
        var target = this.autoCompleteObject.dom;
        var obj = target;
        var width = target.offsetWidth;
        var left = target.offsetLeft;
        var top = target.offsetHeight + target.offsetTop;
        if(window.ActiveXObject){
            try{
                obj = obj.parentNode;
                while(obj && obj.style){
                    obj = obj.parentNode;
                    left += parseInt(obj.offsetLeft) || 0;
                    top += parseInt(obj.offsetTop) || 0;
                }
            }catch(e){}
        }
        var div = document.createElement('div');
        div.className = 'autoCompleteSelector';
        div.style.position = 'absolute';
        div.style.left = left - 1 + 'px';
        div.style.top = top + 'px';
        div.style.width = width  + 'px';
        div.style.height = '200px';
        div.style.overflow = 'auto';
        div.style.display = 'none';
        div.style.zIndex = '1000';
        div.style.border = '1px solid #000';
        div.style.backgroundColor = '#fff';
        document.body.appendChild(div);
        div.autoCompleteSelectorObject = this;
        return div;
    },
    dataCache:[],
    show:function(){
        this.dom.style.display = 'block';
    },
    hide:function(){
        this.dom.style.display = 'none';
    },
    load:function(data){
        this.clear();
        for(var i = 0; i < data.length; i ++){
            this.add(new AutoCompleteSelectItem(data[i],this));
        }
    },
    clear:function(){
        this.dom.innerHTML = '';
    },
    add:function(item){
        this.dom.appendChild(item.dom);    
    },
    remove:function(item){
        this.dom.removeChild(item.dom);    
    }
}

//AutoCompleteSelectItem Class
var AutoCompleteSelectItem = function(data,autoCompleteSelectorObject){
    this.name = data.name;
    this.value = data.value;
    this.dataCache = data;
    this.autoCompleteSelectorObject = autoCompleteSelectorObject;
    this.dom = this.create();
    var __this = this;
    this.dom.onclick = function(){
        __this.autoCompleteSelectorObject.autoCompleteObject.dom.cacheValue = __this.name;
        __this.autoCompleteSelectorObject.autoCompleteObject.dom.value = __this.name;
        __this.autoCompleteSelectorObject.hide();
    }
}
AutoCompleteSelectItem.prototype = {
    create:function(){    
        var div = document.createElement('div');
        div.className = 'autoCompleteSelectItem';
        div.style.width = 'auto';
        div.style.height = '14px';
        div.style.fontSize = '11px';
        div.style.lineHeight = '14px';
        div.style.textAlign = 'left';
        div.style.padding = '2px';
        div.style.borderBottom = '1px solid #ccc';
        div.style.color = '#000';
        div.style.backgroundColor = '#fff';
        div.style.overflow = 'hidden';
        div.onmouseover = function(){
            this.style.backgroundColor = '#999';
            this.style.color = '#fff';
            this.style.cursor = 'pointer';
        }
        div.onmouseout = function(){
            this.style.backgroundColor = '#fff';
            this.style.color = '#000';
        }
        div.innerHTML = this.name;
        div.autoCompleteSelectItem = this;
        return div;
    }
}
  
使用方法是:
var autoCompleteController = new AutoComplete(document.getElementById('keyword'),{
startPoint:3,
JSONService:'autocomplete.php'
});
后台页面(比如:autocomplete.php)接受一个GET方式提交的keyword参数,返回类似
[{"name":"Test1","value":"1"},{"name":"Test2","value":"2"}]
的JSON字符串即可
        代码没有优化,优化方向是:1.进一步解耦 2.增加本地数据缓存的筛选,减少交互次数 3.优化筛选算法
有兴趣的朋友可以去尝试一下。
/*
 *    AutoComplete Class
 *  Author: Robin Chen(robchen@126.com)
*/
//AutoComplete Class
var AutoComplete = function(dom,options){
    this.dom = dom;
    this.startPoint = options.startPoint || 3;
    this.JSONService = options.JSONService;
    this.selector = new AutoCompleteSelector(this);
    var __this = this;
    this.selectMode = true;
    this.dom.onfocus = this.dom.onchange = this.dom.onkeyup = function(){
        setTimeout(function(){
            if(__this.dom.cacheValue != __this.dom.value){
                __this.dom.cacheValue = __this.dom.value;
                __this.search();
            }else{
                if(__this.dom.value.length >= __this.startPoint)__this.selector.show();    
            }
        },10);
    }
    var onMouseClick = function(evt){
        var evt = evt || event;
        var target = evt.target || evt.srcElement;
        if(target != __this.dom && target != __this.selector.dom){
            __this.selector.hide();
        }
    }
    try{
        document.body.attachEvent('onclick',onMouseClick);
    }catch(e){
        document.body.addEventListener('click',onMouseClick,false);    
    }
}
AutoComplete.prototype = {
    request:null,
    dataCache:null,
    createXMLHttpRequest:function(){
        try{
            return new XMLHttpRequest();    
        }catch(e){
            return new ActiveXObject('Microsoft.XMLHTTP');    
        }
    },
    search:function(){
        var keyword = this.dom.value;
        if(keyword.length < this.startPoint)return;
        if(this.request)this.request.abort();
        var request = this.request = this.createXMLHttpRequest();
        request.open('GET',this.JSONService + '?keyword=' + escape(keyword),true);
        var __this = this;
        request.onreadystatechange = function(){
            if(request.readyState == 4 && request.status == 200){
                var data = eval('(' + request.responseText + ')');
                __this.parseData.call(__this,data);
            }
        }
        request.send();
    },
    parseData:function(data){
        this.dataCache = data;
        this.selector.load(data);
        if(this.selector.dom.getElementsByTagName('div').length > 0){
            this.selector.show();
        }else{
            this.selector.hide();    
        }
    }
}
//AutoCompleteSelector Class
var AutoCompleteSelector = function(autoCompleteObject){
    this.autoCompleteObject = autoCompleteObject;
    if(arguments[1]){
        this.dom = arguments[1];
    }else{
        this.dom = this.createDefaultSelectorElement();    
    }
}
AutoCompleteSelector.prototype = {
    createDefaultSelectorElement:function(){
        var target = this.autoCompleteObject.dom;
        var obj = target;
        var width = target.offsetWidth;
        var left = target.offsetLeft;
        var top = target.offsetHeight + target.offsetTop;
        if(window.ActiveXObject){
            try{
                obj = obj.parentNode;
                while(obj && obj.style){
                    obj = obj.parentNode;
                    left += parseInt(obj.offsetLeft) || 0;
                    top += parseInt(obj.offsetTop) || 0;
                }
            }catch(e){}
        }
        var div = document.createElement('div');
        div.className = 'autoCompleteSelector';
        div.style.position = 'absolute';
        div.style.left = left - 1 + 'px';
        div.style.top = top + 'px';
        div.style.width = width  + 'px';
        div.style.height = '200px';
        div.style.overflow = 'auto';
        div.style.display = 'none';
        div.style.zIndex = '1000';
        div.style.border = '1px solid #000';
        div.style.backgroundColor = '#fff';
        document.body.appendChild(div);
        div.autoCompleteSelectorObject = this;
        return div;
    },
    dataCache:[],
    show:function(){
        this.dom.style.display = 'block';
    },
    hide:function(){
        this.dom.style.display = 'none';
    },
    load:function(data){
        this.clear();
        for(var i = 0; i < data.length; i ++){
            this.add(new AutoCompleteSelectItem(data[i],this));
        }
    },
    clear:function(){
        this.dom.innerHTML = '';
    },
    add:function(item){
        this.dom.appendChild(item.dom);    
    },
    remove:function(item){
        this.dom.removeChild(item.dom);    
    }
}
//AutoCompleteSelectItem Class
var AutoCompleteSelectItem = function(data,autoCompleteSelectorObject){
    this.name = data.name;
    this.value = data.value;
    this.dataCache = data;
    this.autoCompleteSelectorObject = autoCompleteSelectorObject;
    this.dom = this.create();
    var __this = this;
    this.dom.onclick = function(){
        __this.autoCompleteSelectorObject.autoCompleteObject.dom.cacheValue = __this.name;
        __this.autoCompleteSelectorObject.autoCompleteObject.dom.value = __this.name;
        __this.autoCompleteSelectorObject.hide();
    }
}
AutoCompleteSelectItem.prototype = {
    create:function(){    
        var div = document.createElement('div');
        div.className = 'autoCompleteSelectItem';
        div.style.width = 'auto';
        div.style.height = '14px';
        div.style.fontSize = '11px';
        div.style.lineHeight = '14px';
        div.style.textAlign = 'left';
        div.style.padding = '2px';
        div.style.borderBottom = '1px solid #ccc';
        div.style.color = '#000';
        div.style.backgroundColor = '#fff';
        div.style.overflow = 'hidden';
        div.onmouseover = function(){
            this.style.backgroundColor = '#999';
            this.style.color = '#fff';
            this.style.cursor = 'pointer';
        }
        div.onmouseout = function(){
            this.style.backgroundColor = '#fff';
            this.style.color = '#000';
        }
        div.innerHTML = this.name;
        div.autoCompleteSelectItem = this;
        return div;
    }
}使用方法是:
var autoCompleteController = new AutoComplete(document.getElementById('keyword'),{
startPoint:3,
JSONService:'autocomplete.php'
});
后台页面(比如:autocomplete.php)接受一个GET方式提交的keyword参数,返回类似
[{"name":"Test1","value":"1"},{"name":"Test2","value":"2"}]
的JSON字符串即可
                  
                  
                  
                  
                            
本文介绍了一种利用AJAX实现自动完成搜索建议的方法。通过JavaScript代码,当用户输入达到预设长度时,会发送请求到服务器获取匹配项,并显示在输入框下方供选择。
          
    
      
          
                
                
                
                
              
                
                
                
                
                
              
                
                
              
            
                  
					129
					
被折叠的  条评论
		 为什么被折叠?
		 
		 
		
    
  
    
  
            


            