zoukankan      html  css  js  c++  java
  • 【转】仿百度输入框智能提示的js代码

    转自:http://www.jb51.net/article/40783.htm

    对于我这个JS菜鸟,能找到这样的实属不容易啊!!!

    刚开始老大让做这个功能,真是一点头绪都没有,万分感谢!!!

    最近客户需求老是变更,不过有些是因为客户催得急,我没有那么快能完成,所以先做了一个雏形给他们,后来再慢慢改。比如雏形那里我做了一个下拉列表 给他们,事实上他们的数据有200多条,用个下拉列表的话很不现实,你能找那么多?而且那个下拉列表该有多长啊?所以很自然的,我想到了百度那个智能提示 的功能。

    参考了一下之前忘记是哪位大侠写的东西,他的是使用百度api的,为了简单起见,我把数据都定在了js那里,这样看官们容易理解一些。

    还是整个代码考上来吧,代码不长。考了一下之前忘记是哪位大侠写的东西,他的是使用百度api的,为了简单起见,我把数据都定在了js那里,这样看官们容易理解一些。

    代码如下(改良版:增加键盘上下回车选择):


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <title>测试提示框</title>
    
        <script type="text/javascript" src="js/jquery-1.4.2.js"></script>
        <style type="text/css">
            .search
            {
                left: 0;
                position: relative;
            }
            #auto_div
            {
                display: none;
                width: 300px;
                border: 1px #74c0f9 solid;
                background: #FFF;
                position: absolute;
                top: 24px;
                left: 0;
                color: #323232;
            }
        </style>
        <!-- <script src="jquery-1.7.2.min.js" type="text/javascript"></script> -->
        <script type="text/javascript">
            //测试用的数据
            var test_list = ["小张", "小苏", "小杨", "老张", "老苏", "老杨", "老爷爷", "小妹妹", "老奶奶", "大鹏", "大明", "大鹏展翅", "你好", "hello", "hi"];
            var old_value = "";
            var currentSelIndex = -1;
            var oldSelIndex = -1;
    
            //自动完成
            function AutoComplete(auto, search, mylist, event) {
                if ($("#" + search).val() != old_value || old_value == "" 
                    || event.keyCode == 40 || event.keyCode == 38 || event.keyCode == 13) {
                    var autoNode = $("#" + auto);   //缓存对象(弹出框)
                    var carlist = new Array();
                    var n = 0;
                    old_value = $("#" + search).val();
    
                    for (i in mylist) {
                        if (mylist[i].indexOf(old_value) >= 0) {
                            carlist[n++] = mylist[i];
                        }
                    }
                    if (carlist.length == 0) {
                        autoNode.hide();
                        return;
                    }
                    autoNode.empty();  //清空上次的记录
                    for (i in carlist) {
                        var wordNode = carlist[i];   //弹出框里的每一条内容
    
                        var newDivNode = $("<div>").attr("id", i);    //设置每个节点的id值
                        newDivNode.attr("style", "font:14px/25px arial;height:25px;padding:0 8px;cursor: pointer;");
    
                        newDivNode.html(wordNode).appendTo(autoNode);  //追加到弹出框
    
                        //鼠标移入高亮,移开不高亮
                        newDivNode.mouseover(function () {
                            if (currentSelIndex != -1) {        //原来高亮的节点要取消高亮(是-1就不需要了)
                                autoNode.children("div").eq(currentSelIndex).css("background-color", "white");
                            }
                            //记录新的高亮节点索引
                            currentSelIndex = $(this).attr("id");
                            $(this).css("background-color", "#ebebeb");
                        });
                        newDivNode.mouseout(function () {
                            $(this).css("background-color", "white");
                        });
    
                        //鼠标点击文字上屏
                        newDivNode.click(function () {
                            //取出高亮节点的文本内容
                            var comText = autoNode.hide().children("div").eq(currentSelIndex).text();
                            currentSelIndex = -1;
                            //文本框中的内容变成高亮节点的内容
                            $("#" + search).val(comText);
                        })
                        if (carlist.length > 0) {    //如果返回值有内容就显示出来
                            autoNode.show();
                        } else {               //服务器端无内容返回 那么隐藏弹出框
                            autoNode.hide();
                            //弹出框隐藏的同时,高亮节点索引值也变成-1
                            currentSelIndex = -1;
                        }
                    }
                    
                 // 通过键盘上下键来进行选择,回车键进行确定
                    var listLength = carlist.length;
                    //currentSelIndex = currentSelIndex;
                    if(event.keyCode == 40 || event.keyCode == 38){    
                        if(event.keyCode == 40 )    // 下移
                        {
                            if (currentSelIndex == listLength - 1) {
                                currentSelIndex = 0;
                            }
                            else {
                                currentSelIndex = currentSelIndex + 1;
                                if (currentSelIndex > listLength - 1) {
                                    currentSelIndex = 0;
                                }
                            }
                        }
                        if(event.keyCode == 38 )    // 上移
                        {
                            if (currentSelIndex == -1) {
                                currentSelIndex = listLength - 1;
                            }
                            else {
                                currentSelIndex = currentSelIndex - 1;
                                if (currentSelIndex < 0) {
                                    currentSelIndex = listLength - 1;
                                }
                            }
                        }
                        if (currentSelIndex != -1) {
                            autoNode.children("div").eq(currentSelIndex).css("background-color", "#4778DA");
                            selectedFlag = true;
                        }
                        if (oldSelIndex != -1) {
                            autoNode.children("div").eq(oldSelIndex).css("background-color", "#ffffff");
                        }
                    }
                    if(event.keyCode == 13)
                    {
                        var comText = autoNode.hide().children("div").eq(currentSelIndex).text();
                        currentSelIndex = -1;
                        //文本框中的内容变成高亮节点的内容
                        $("#" + search).val(comText);
                        autoNode.hide();
                    }
                }
    
                //点击页面隐藏自动补全提示框
                document.onclick = function (e) {
                    var e = e ? e : window.event;
                    var tar = e.srcElement || e.target;
                    if (tar.id != search) {
                        if ($("#" + auto).is(":visible")) {
                            $("#" + auto).css("display", "none")
                        }
                    }
                }
            }
    
            $(function () {
                old_value = $("#search_text").val();
                $("#search_text").focus(function (event) {
                    if ($("#search_text").val() == "") {
                        AutoComplete("auto_div", "search_text", test_list, event);
                    }
                });
    
                $("#search_text").keyup(function (event) {
                    AutoComplete("auto_div", "search_text", test_list, event);
                });
            });
        </script>
    </head>
    <body>
        <div class="search">
            <input type="text" id="search_text" />
            <div id="auto_div">
            </div>
        </div>
    </body>
    </html>

    另外附上另一个大神的只是上下移动的,并且可以自动填充的搜索框:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <style type="text/css">
            ul,li{list-style-type:none;}
        </style>
        <script type="text/javascript" language="javascript">
            var currentSelIndex = -1;
            var oldSelIndex = -1;
    
            function selectItem(keyword, event) {
                if (keyword == "") {
                    document.getElementById("ulItems").style.display = "none";
                    return;
                }
                else {
                    var liLength = document.getElementById("ulItems").getElementsByTagName("li").length; //获取列表数量
                    if ((event.keyCode == 38 || event.keyCode == 40) && document.getElementById("ulItems").style.display != "none") {
                        if (liLength > 0) {
                            oldSelIndex = currentSelIndex;
                            //上移
                            if (event.keyCode == 38) {
                                if (currentSelIndex == -1) {
                                    currentSelIndex = liLength - 1;
                                }
                                else {
                                    currentSelIndex = currentSelIndex - 1;
                                    if (currentSelIndex < 0) {
                                        currentSelIndex = liLength - 1;
                                    }
                                }
                                if (currentSelIndex != -1) {
                                    document.getElementById("li_" + currentSelIndex).style.backgroundColor = "#cbf3fd";
                                    document.getElementById("txtKeyword").value = document.getElementById("li_" + currentSelIndex).innerText;
                                }
                                if (oldSelIndex != -1) {
                                    document.getElementById("li_" + oldSelIndex).style.backgroundColor = "#ffffff";
                                }
                            }
                            //下移
                            if (event.keyCode == 40) {
                                if (currentSelIndex == liLength - 1) {
                                    currentSelIndex = 0;
                                }
                                else {
                                    currentSelIndex = currentSelIndex + 1;
                                    if (currentSelIndex > liLength - 1) {
                                        currentSelIndex = 0;
                                    }
                                }
                                if (currentSelIndex != -1) {
                                    document.getElementById("li_" + currentSelIndex).style.backgroundColor = "#cbf3fd";
                                    document.getElementById("txtKeyword").value = document.getElementById("li_" + currentSelIndex).innerText;
                                }
                                if (oldSelIndex != -1) {
                                    document.getElementById("li_" + oldSelIndex).style.backgroundColor = "#ffffff";
                                }
                            }
                        }
                    }
                    else if (event.keyCode == 13) {
                        if (document.getElementById("ulItems").style.display != "none" && liLength > 0 && currentSelIndex != -1) {
                            document.getElementById("txtKeyword").value = document.getElementById("li_" + currentSelIndex).innerText;
                            document.getElementById("ulItems").style.display = "none";
                            currentSelIndex = -1;
                            oldSelIndex = -1;
                        }
                    }
                    else {
                        autoComplete(keyword);
                        document.getElementById("ulItems").style.display = "";
                        currentSelIndex = -1;
                        oldSelIndex = -1;
                    }
                }            
            }
    
            function autoComplete(keyword) {
                var liHtml0 = "<li id="li_0">1</li><li id="li_1">12</li><li id="li_2">123</li><li id="li_3">1234</li>";
                var liHtml1 = "<li id="li_0">12</li><li id="li_1">123</li><li id="li_2">1234</li>";
                var liHtml2 = "<li id="li_0">123</li><li id="li_1">1234</li>";
                var liHtml3 = "<li id="li_0">1234</li>";
                if (keyword == "1234") {
                    document.getElementById("ulItems").innerHTML = liHtml3;
                }
                else if (keyword == "123") {
                    document.getElementById("ulItems").innerHTML = liHtml2;
                }
                else if (keyword == "12") {
                    document.getElementById("ulItems").innerHTML = liHtml1;
                }
                else if (keyword == "1") {
                    document.getElementById("ulItems").innerHTML = liHtml0;
                }
                else {
                    document.getElementById("ulItems").innerHTML = "";
                }
            }
        </script>
    </head>
    <body>
        <input id="txtKeyword" type="text" onkeyup="selectItem(this.value, event)" style="200px;" />
        <ul id="ulItems" style="display: none; border:1px solid #cecece; border-top:none; 200px; padding:2px; margin:0px;">
        </ul>
    </body>
    </html>


    大家复制代码的时候记得把jquery带上,不然出错了又要来骂娘了……

    说说主要的思路吧。

    首先,把数据弄成一个js数组,然后遍历这个数组,每一条数据生成一个div,然后添加到auto_div这个div里,还要设置一下鼠标移过高 亮,移开恢复正常,以及点击的时候自动填上文本框里,还有鼠标在网页点击的时候列表框会消失——当然还有更多细节要注意,这里只是举个例子。怎样让文本框 里的文本改变的时候就触发AutoComplete事件呢?用onchange?错,onchange是文本框失去光标的时候才会触发,所以使用 keyup事件会好一点。

    别的不多说,代码也不难看懂,原理也很简单。我要强调的一点是,像这种智能提示功能可能有些新手会想到用模糊搜索,当文本框里的文本改变的时候就去 查一下数据库,把返回的数据列出来——这是不好的做法,我不说他错误因为这样确实可行,但是这会给服务器造成太大的负担,每改变一下文本就查一下数据库, 就好像我每要一样东西就要向你问一下一样,倒不如你一次把它们全给我,我要什么自己选。当然凡事都有两面性,把所有数据一次性查出来的后果是耗内存,大数 据不建议这样做,这种做法适用于大部分情况,因为大部分情况都不是大数据——大数据的,另想它法。

    最后说说我的感受:之前面试过前端工程师,那时候人家觉得我还嫩,确实那时候特嫩。现在,我在前端的领域正开始慢慢强大起来,虽然公司没有前端工程师,但是我还是觉得前端很重要,我要合理运用前端来解决一些用前端很简单就能解决的问题,而不是丢给后台来处理。

    在公司做着做着,虽然跟别人学到的东西不多,但是需求来了,自己想办法以及在网上找一些解决方案,自己也学到不少东西。继续做,加油!

  • 相关阅读:
    ASPX属性菜单ASTreeView
    MD5 encryption(Hash Algorithm)
    Asp.net的身份验证
    log4net使用
    脚本正则表达式
    C#操作注册表
    利用JQuery的.getJSON给Dropdownlist绑定Item
    查看mysql的端口号
    用SQL语句的方法还原数据库
    MYSQL 乱码 ERROR 1366
  • 原文地址:https://www.cnblogs.com/gmq-sh/p/4306248.html
Copyright © 2011-2022 走看看