返回介绍

jQuery autocomplete 自扩展插件、自动补全示例

发布于 2025-02-25 12:38:57 字数 11697 浏览 0 评论 0 收藏 0

jquery-lib 版本是 1.3.2 的,该插件是简单的扩展插件,代码也比较简单的封装。所以看起来也比较简单不是很费力,当然封装得也不是很好。不过做了浏览器方面的兼容,经测试兼容 IE6+、Firefox3.5+

首先看看 autocomplete.js:

;(function ($) {
  var index = -1;
  var timeId;

  var cssOptions = {
    "border": "1px solid black",
    "background-color": "white",
    "position": "absolute"/*,
    "font": "normal normal lighter 14px 6px Times New Roman"*/
  };

  var defaults = {
    width: "auto",
    highlightColor: "#3399FE",
    unhighlightColor: "#FFFFFF",
    css: cssOptions,
    dataType: "xml",
    paramName: "word",
    delay: 500,
    max: 20
  };

  var keys = {
    UP: 38,
    DOWN: 40,
    DEL: 46,
    TAB: 9,
    ENTER: 13,
    ESC: 27,
    /*COMMA: 188,*/
    PAGEUP: 33,
    PAGEDOWN: 34,
    BACKSPACE: 8,
    A: 65,
    Z: 90
  };

  $.fn.extend({
    autocomplete: function (sUrl, settings) {

      sUrl = (typeof sUrl === "string") ? sUrl : "";
      var param = !this.attr("id") ? defaults.paramName : this.attr("id"); 

      settings = $.extend({}, defaults, {url: sUrl, paramName: param}, settings);
      var autoTip = this.autoTipTemplate(this, settings);
      $("body").append(autoTip);
      var $this = this;
      this.keyup(function (event) {
        $this.keyOperator(event, autoTip, settings);
      });
      /*$("input[type=button]").click(function () {
        $("#result").text("文本框中的【" + search.val() + "】被提交了!");
        $("#auto").hide();
        index = - 1;
      });*/
      return this.each(function () {
        $this.val();
      });
    },
    autoTipTemplate: function (input, settings) {
      var inputOffset = input.offset();

      var autoTip = $("<div/>").css(settings.css).hide()
      .css("top", inputOffset.top + input.height() + 5 + "px")
      .css("left", inputOffset.left + "px");

      var space = $.browser.mozilla ? 2 : 6;//兼容浏览器
      var tipWidth = (typeof settings.width === "string" && "auto") ? input.width() : settings.width;
      autoTip.width(tipWidth + space + "px");

      return autoTip;
    },
    select: function (target, index, settings, flag) {
      var color = flag ? settings.highlightColor : settings.unhighlightColor;
      target.children("div").eq(index).css("background-color", color);
    },
    keyOperator: function (event, autoTip, settings) {
      var evt = event || window.event;
      var autoNodes = autoTip.children("div");

      var kc = evt.keyCode;
      var $this = this;

      /* 当用户按下字母或是 delete 或是退格键*/
      if (kc >= keys.A && kc <= keys.Z || kc == keys.BACKSPACE || kc == keys.DEL) {
        var wordText = this.val();
        if (wordText.length != 0) {
          var param = {};
          param[settings.paramName] = wordText;

          clearTimeout(timeId);
          timeId = setTimeout(function () {
            $.post(settings.url, param, function (data) {
              var wordObj = $(data);
              if (settings.dataType == "xml") {
                var wordNodes = wordObj.find("word");
                autoTip.html("");
                wordNodes.each(function (i) {
                  var divNode = $("<div>").attr("id", i);
                  //将遍历的单词加入到创建的 div 中,然后把该 div 追加到 auto 中
                  divNode.html($(this).text()).appendTo(autoTip);
                  //鼠标已进去,添加高亮
                  divNode.mousemove(function () {
                    //如果已经存在高亮,去掉高亮改为白色
                    if (index != -1) {
                      autoTip.children("div").eq(index).css("background-color", settings.unhighlightColor);
                    } 
                    index = $(this).attr("id");
                    $(this).css("background-color", settings.highlightColor);
                  });
                  //鼠标移出,取消高亮
                  divNode.mouseout(function () {
                    $(this).css("background-color", settings.unhighlightColor);
                  });
                  //点击高亮内容
                  divNode.click(function () {
                    $this.val($(this).text());
                    index = -1;
                    autoTip.hide();
                  });
                });

                if (wordNodes.length > 0) {
                  autoTip.show();
                } else {
                  autoTip.hide();
                  index = -1;
                }
              }
            });
          }, settings.delay);
        } else {
          autoTip.hide();
          index = -1;
        }
      } else if (kc == keys.UP || kc == keys.DOWN) {/*当用户按下上下键*/
         if (kc == keys.UP) {//向上
           if (index != -1) {
             autoNodes.eq(index).css("background-color", settings.unhighlightColor);
             index--;
           } else {
             index = autoNodes.length - 1;
           }
           if (index == -1) {
             index = autoNodes.length - 1;
           }
           autoNodes.eq(index).css("background-color", settings.highlightColor);
         } else {//向下
           if (index != -1) {
             autoNodes.eq(index).css("background-color", settings.unhighlightColor);
           }
           index++;
           if (index == autoNodes.length) {
             index = 0;
           }
           autoNodes.eq(index).css("background-color", settings.highlightColor);
         }      
      } else if (kc == keys.PAGEUP || kc == keys.PAGEDOWN) {
        event.preventDefault();
         if (kc == keys.PAGEUP) {
           if (index != -1) {
             autoNodes.eq(index).css("background-color", settings.unhighlightColor);
           } 
           if (autoNodes.length > 0) {
             index = 0;
             autoNodes.eq(0).css("background-color", settings.highlightColor);
           }
         } else {
           if (index != -1) {
             autoNodes.eq(index).css("background-color", settings.unhighlightColor);
           }
           index = autoNodes.length - 1;             
           autoNodes.eq(index).css("background-color", settings.highlightColor);
         }      
      } else if (kc == keys.ENTER) {
        //回车键      
        //有高亮内容就补全信息
        if (index != -1) {
          $this.val(autoNodes.eq(index).text());
        } else {//没有就隐藏
          $("body").append($("<div/>").text("文本框中的【" + $this.val() + "】被提交了!"));
          $this.get(0).blur();
        }
        autoTip.hide();
        index = -1;
      } else if (kc == keys.ESC) {
        autoTip.hide();
      }
    }
  });
})(jQuery);

现在来分析上面的 autocomplete 插件的一些常用选项:
index 就是选择提示选项高亮的索引;
timeId 是当用户在文本域输入时,利用 setTimeout 进行 ajax 请求服务器获得数据的而返回的时间;
cssOptions 是自动提示选项的样式,这里给出了一些默认的样式;

var defaults = {  
    width: "auto",//默认或自动设置宽度  
    highlightColor: "#3399FE",//高亮时的颜色  
    unhighlightColor: "#FFFFFF",//非高亮时的颜色  
    css: cssOptions,  
    dataType: "xml",//ajax 请求返回数据类型  
    paramName: "word",//ajax 请求的参数名称,如果你有设置文本域的 id,那么就使用这个属性  
    delay: 500,//当文本域在不停的输入时,ajax 多久请求一次服务器  
  };   

keys 就是键盘键对应的值;
autocomplete 就是调用的函数,可以在里面设置 ajax 请求的 url,以及配置上面 defaults 中出现的参数,这个方法返回的是文本域的值;
autoTipTemplate 就是输入时显示的提示框、提示菜单,返回的是一个 jquery 对象;
select 是选择提示菜单也就是下来提示菜单的高亮选项,target 当然是目标对象了,index 是即将被高亮的选项的索引,settings 就是
高亮的颜色配置,这个在默认 defaults 中就有的。是通过$.extend 方法将 defaults 对象的属性赋值给 settings 对象的;
keyOperator 是针对文本域的键盘操作,这个是核心函数;操作提示、自动补全就靠它了;

下面看看 html 代码,看看是如何调用 autocomplete 插件的:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <title>Ajax 示例,实现 Google 搜索补全功能</title>

  <meta http-equiv="author" content="hoojo">
  <meta http-equiv="email" content="hoojo_@126.com">
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <script type="text/javascript" src="jslib/jquery-1.3.2.min.js"></script>
  <script type="text/javascript" src="jslib/jquery.autocomplete-1.2.js"></script>
  <script type="text/javascript">
    $(function () {
      $(":text").autocomplete("AutocompleteWordServlet", {dataType: "xml", width: "auto"});
    });
  </script>
  </head>

  <body>
     请输入:<input type="text" />
     <input type="button" value="Go" /><br/><br/>
  </body>
</html>

看看这段代码 AutocompleteWordServlet 是请求的 Servlet,dataType 是 ajax 请求服务器端的返回数据的类型,width 可以设置自动提示菜单的宽度。

怎么样,用法比较简单吧。当然后面你还可以加其他的配置,如:

代码片段

$(":text").autocomplete("AutocompleteWordServlet", {
        width: "auto",
        highlightColor: "#3355FE",
        unhighlightColor: "#FFFFcc",
        css: {border: "2px solid red"},
        dataType: "xml",
        paramName: "keyWord",
        delay: 300
      });

这样也是可以的;

看看 AutocompleteWordServlet 的代码:

package com.hoo.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class AutocompleteWordServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    String word = request.getParameter("word");
    request.setAttribute("word", word);
    //System.out.println(word);
    request.getRequestDispatcher("word.jsp").forward(request, response);
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}

没什么可说的,就是获取客户端文本域的 ajax 请求的关键字,然后在 jsp 页面中进行单词过滤。不过你也可以在客户端用正则

或是在服务器端用正则过滤都是可以的。

下面看看 word.jsp 的内容:

<%@ page language="java" contentType="text/xml; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<words>
  <c:if test="${fn:startsWith('abstruct', word)}">
    <word>abstruct</word>
  </c:if>
  <c:if test="${fn:startsWith('anilazine', word)}">
    <word>anilazine</word>
  </c:if>
  <c:if test="${fn:startsWith('appeared', word)}">
    <word>appeared</word>
  </c:if>
  <c:if test="${fn:startsWith('autocytolysis', word)}">
    <word>autocytolysis</word>
  </c:if>
  <c:if test="${fn:startsWith('apple', word)}">
    <word>apple</word>
  </c:if>
  <c:if test="${fn:startsWith('boolean', word)}">
    <word>boolean</word>
  </c:if>
  <c:if test="${fn:startsWith('break', word)}">
    <word>break</word>
  </c:if>
  <c:if test="${fn:startsWith('bird', word)}">
    <word>bird</word>
  </c:if>
  <c:if test="${fn:startsWith('blur', word)}">
    <word>blur</word>
  </c:if>
  <c:if test="${fn:startsWith('call', word)}">
    <word>call</word>
  </c:if>
  <c:if test="${fn:startsWith('class', word)}">
    <word>class</word>
  </c:if>
  <c:if test="${fn:startsWith('card', word)}">
    <word>card</word>
  </c:if>
  <c:if test="${fn:startsWith('dacnomania', word)}">
    <word>dacnomania</word>
  </c:if>
  <c:if test="${fn:startsWith('document', word)}">
    <word>document</word>
  </c:if>
</words>

就是一个 xml 格式的文档,通过使用 jstl 表达式,用 startsWith 函数匹配,如果通过就显得在 xml 内容中,还有看到上面的 contentType="text/xml; charset=UTF-8" ​了没有,是 text/xml 哦!这点要注意,如果不设置有的浏览器就不能解析了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文