类似google的下拉列表

suggest.js

/***********************************************
 * Global variables
 *在原有基础上增加传递object对象,
 *修改(suggest(keywords,key,object))方法
 *修改(navigate(key,object))方法
 *修改tabfix(keywords, key,object)方法
 *修改populate(a,object)方法
 ***********************************************/
var maxResults = 10;    // max # of results to display控制最大显示数
var ignoreKeys = "";

/***********************************************
 * Prototype for populating data
 ***********************************************/
function get_data() {}

/***********************************************
 * Find search keys in data set
 ***********************************************/
function suggest(keywords,key,object)
{
    //alert("line 19="+object.id);
    var results = document.getElementById("results");
    
    if(keywords != "")
    {
        var terms = get_data(); // sort? -- data should be alphabetical for best results

        var ul = document.createElement("ul");
        var li;
        var a;
        
        if ((key.keyCode == '40' || key.keyCode == '38' || key.keyCode == '13'))
        {
            navigate(key.keyCode,object);
        }
        else
        {
            var kIndex = -1;
        
            for(var i = 0; i < terms.length; i++)
            {    
                kIndex = terms[i].activity.toLowerCase().indexOf(keywords.toLowerCase());
                
                if(kIndex >= 0)
                {
                    li = document.createElement("li");
                    
                    // setup the link to populate the search box
                    a = document.createElement("a");
                    a.href = "javascript://";
                    
                    a.setAttribute("rel",terms[i].val);
                    a.setAttribute("rev", getRank(terms[i].activity.toLowerCase(), keywords.toLowerCase()));
                    a.setAttribute("ref",terms[i].val2);
                    
                    if(!document.all) a.setAttribute("onclick","populate(this,object);");
                    else a.onclick = function() { populate(this,object); }
                    
                    
                    
                    a.appendChild(document.createTextNode(""));
                    
                    if(keywords.length == 1)
                    {
                        var kws = terms[i].activity.toLowerCase().split(" ");
                        //alert("line 68="+kws+terms[i].val2);

                        var firstWord = 0;
                        
                        for(var j = 0; j < kws.length; j++)
                        {
                         //    if(kws[j].toLowerCase().charAt(0) == keywords.toLowerCase()) {
                                
                                ul.appendChild(li);
                                
                                if(j != 0) {
                                    kIndex = terms[i].activity.toLowerCase().indexOf(" " + keywords.toLowerCase());
                                    kIndex++;
                                }
                                
                                break;
                        //    }
                        }
                    }
                    else if(keywords.length > 1) {
                        ul.appendChild(li);
                    }
                    else continue;

                    
                    var before = terms[i].activity.substring(0,kIndex);
                    var after = terms[i].activity.substring(keywords.length + kIndex, terms[i].activity.length);
    
                    a.innerHTML = before + "<strong>" + keywords.toLowerCase() + "</strong>" + after;
    
                    li.appendChild(a);

                }
            }        
            
            if(results.hasChildNodes()) results.removeChild(results.firstChild);
            
            // position the list of suggestions
            var s = document.getElementById(object.id);
            var xy = findPos(s);
    
            results.style.left = xy[0] + "px";
            results.style.top = xy[1] + s.offsetHeight + "px";
            results.style.width = s.offsetWidth + "px";
            
            // if there are some results, show them
            if(ul.hasChildNodes()) {
                results.appendChild(filterResults(ul));
                
                if(results.firstChild.childNodes.length == 1) results.firstChild.firstChild.getElementsByTagName("a")[0].className = "hover";
                
            }

        }
    }
    else
    {
        if(results.hasChildNodes()) results.removeChild(results.firstChild);
    }
}

/***********************************************
 * Rank results - used for sorting result sets
 * 0 if entire row starts with kw
 * 0 < i < 1 if any word in row starts with kw (1k char max)
 * i > 1 if row contains kw anywhere else
 ***********************************************/
function getRank(activity, keywords)
{
    var ret = -1;
    var kIndex = activity.indexOf(keywords);
    
    ret = (activity.charAt(kIndex - 1) == " ") ? kIndex : (200*kIndex);
    
    return ret;    
}

/***********************************************
 * Sort the result suggestion sets
 ***********************************************/
function filterResults(s)
{
    var sorted = new Array();
    
    for(var i = 0; i < s.childNodes.length; i++)
    {
        sorted.push(s.childNodes[i]);
    }
    
    var ul = document.createElement("ul");
    var lis = sorted.sort(sortIndex);
    
    for(var j = 0; j < lis.length; j++)
    {
        if(j < maxResults) ul.appendChild(lis[j]);
        else break;
    }

    return ul;
    
}

function sortIndex(a,b)
{
    // wow thats ugly -- need logic around grouped items getting out of order
    return (a.getElementsByTagName("a")[0].rev - b.getElementsByTagName("a")[0].rev);
}


/***********************************************
 * Navigate using up/down and submit with 'Enter'
 ***********************************************/
function navigate(key,object)
{
    var results = document.getElementById("results");
    var keyIndex = document.getElementById("keyIndex");
    
    var i = keyIndex.value;
    
    if(i == "" || !i) i = -1;
    else i = parseFloat(i);

    var ul = results.childNodes[0];

    if(ul)
    {
        if(key == '40') // DOWN
        {
            i++;
            if(i > ul.childNodes.length-1) i = ul.childNodes.length-1;
            
            keyIndex.value = i;
            
            try {
                ul.childNodes[i].getElementsByTagName("a")[0].className = "hover";
                ul.childNodes[i-1].getElementsByTagName("a")[0].className = "";
            }
            catch(e) {}
        }
        else if(key == '38') // UP
        {
            i--;
            if(i <= 0) i = 0;
            
            keyIndex.value = i;
            
            try {
                ul.childNodes[i].getElementsByTagName("a")[0].className = "hover";
                ul.childNodes[i+1].getElementsByTagName("a")[0].className = "";
            }
            catch(e) {}
        }
        else if(key == '13' || key == '9') // ENTER/TAB -- POPULATE
        {
            if(i == -1) i = 0;
            populate(ul.childNodes[i].getElementsByTagName("a")[0],object);
        }
        else return;    
    }
}

/***********************************************
 * Allow for using tab onkeydown
 ***********************************************/
function tabfix(keywords, key,object)
{
    if(key.keyCode == '9') {
        navigate(key.keyCode,object);
        return false;
    }
    else return true;
}

/***********************************************
 * Populate hidden fields via onclick on 'Enter'
 ***********************************************/
function populate(a,object)
{
    
    var ul = document.getElementById("results").childNodes[0];
    
    try {
        var pick = a.innerHTML.replace("<strong>","").replace("</strong>","");
        //alert("line 251="+a);
        //alert(a.getAttribute("ref"));
        // IE6 converts HTML elements to uppercase -- could be done with RegExp
        if(document.all) pick = a.innerHTML.replace("<STRONG>","").replace("</STRONG>","");
        
        //document.getElementById("s").value = pick;
        //document.getElementById(object.id).value = pick;
        document.getElementById(object.id).value = a.getAttribute("ref");
    }
    catch(e) {}
    
    clearSuggest();
}

/***********************************************
 * Find an elements position on the screen
 ***********************************************/
function findPos(obj)
{
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        curleft = obj.offsetLeft
        curtop = obj.offsetTop
        while (obj = obj.offsetParent) {
            curleft += obj.offsetLeft
            curtop += obj.offsetTop
        }
    }
    return [curleft,curtop];
}

/***********************************************
 * Helper to preserve onclick on suggestions
 ***********************************************/
function clearSuggest()
{
    // need a timeout so the onclick event is captured before results are hidden
    setTimeout("hideSuggest()",200);  //time set选择时间设置
}

/***********************************************
 * Hide the suggestions list and remove from DOM
 ***********************************************/
function hideSuggest()
{
    var results = document.getElementById("results");
    if(results.hasChildNodes()) results.removeChild(results.firstChild);
    
    document.getElementById("keyIndex").value = "-1"; // reset the suggestions index
}



style.css

.nodisplay {
    display: none;
}

label {
    float: left;
    font: normal 12px Arial;
    width: 80px;
}

#s {
    width: 300px;
}

#results {
    position: absolute;
    top: 0;
    left: 0;
    width: 300px;
}

#results ul {
    border: 1px solid #bfbfbf;
    margin: 0;
    padding: 0;
    list-style: none;
    width: 100%;
}

#results ul li {

}

#results ul li a {
    display: block;
    color: #444;
    background: #fff;
    font: normal 12px arial;
    text-decoration: none;
    padding: 1px 4px 2px 6px;
}

* html #results ul li a {
    width: 100%;
}

#results ul li a strong {
    color: red;
}

#results ul li a:hover, #results ul li a.hover {
    background: #0056f4;
    color: #fff;
}

#results ul li a:hover strong, #results ul li a.hover strong {
    color: #fff;
}



index.html

<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
   
    <style type="text/css">
        @import "style.css";
    </style>
   
    <script type="text/javascript" src="suggest.js"></script>

    <script type="text/javascript">
        function get_data()
        {
            var terms = new Array();
           
            terms.push({val:1,activity:"c",val2:"c"});
            terms.push({val:1,activity:"cs",val2:"cs"});
            terms.push({val:1,activity:"css",val2:"css"});
            terms.push({val:1,activity:"cssr",val2:"cssr"});
            terms.push({val:1,activity:"cssra",val2:"cssra"});
            terms.push({val:1,activity:"cssrai",val2:"cssrai"});
            terms.push({val:1,activity:"cssrain",val2:"cssrain"});
            terms.push({val:1,activity:"[shenyang]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;沈阳",val2:"沈阳"});
            terms.push({val:1,activity:"[shenzhen]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;深圳",val2:"深圳"});
            terms.push({val:1,activity:"[shanghai]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;上海",val2:"上海"});
            terms.push({val:1,activity:"[shongyuan]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;松原",val2:"松原"});
            terms.push({val:1,activity:"[guangzhou]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;广州",val2:"广州"});
            terms.push({val:1,activity:"[guangdong]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;广东",val2:"广东"});
           
            return terms;   
        }
    </script>
   
</head>
<body>

    <form action="">
   
        <p>字符测试:请输入c,s,s,r,a,i,n测试</p>
        <p>中文测试:请输入"沈阳","深圳","松原","广州"测试</p>
        <p>
            <label for="s">Search:</label>
            <input id="s" type="text" onkeyup="suggest(this.value,event,this);" onkeydown="return tabfix(this.value,event,this);" onblur="clearSuggest();" />
            <input id="s1" type="text" onkeyup="suggest(this.value,event,this);" onkeydown="return tabfix(this.value,event,this);" onblur="clearSuggest();" />
        </p>
        <p class="nodisplay">
            <label>kIndex</label>
            <input class="nodisplayd" type="text" id="keyIndex" />
        </p>
        <p class="nodisplay">
            <label>rev</label>
            <input class="nodisplayd" type="text" id="sortIndex" />
        </p>
       
        <div id="results"></div>

       
    </form>
   
</body>
</html>

posted @ 2009-09-19 11:09  chaobj  阅读(444)  评论(0编辑  收藏  举报