java+jquerygoogle百度搜索自动提示效果
自动补齐功能的实现(仿google、百度搜索框)

else if (window.ActiveXObject) { // IE浏览器
try {
obj = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e){
try{
}
}
function suggestOver(div_value){
div_value.className = "suggest_link_over";
}
function suggestOut(div_value){
div_value.className = "suggest_link";
<ቤተ መጻሕፍቲ ባይዱhtml>
2.1,Server.aspx(数据提供页,此页面中删除其它多余代码,只留最上面一行。如果这里改了名请记得显示页面的调用处也要改哈-_-)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Server.aspx.cs" Inherits="Server" %>
padding: 2px 6px 2px 6px;
}
.suggest_link_over
{
background-color: #E8F2FE;
padding: 2px 6px 2px 6px;
}
#search_suggest
var s='<div onmouseover="javascript:suggestOver(this);"';
利用JavaScript和ASP.NET获取各大搜索引擎的自动提示

可 以看 出返 回结 果是 J S O N P格 式 的 结 果 ,在 实 际 应 用 程 序 中 ,可 以 在 回调 函 数 中 对 返 回 的 J S O N P结 果 进 行 解 析 f P a r s e ) 成 具 体 应 用 程 序需 要 的格 式 。 以 下 是输 入一 个 关 键 字 并 通 过 回
A S 4 I I I I I H C S ” : 0 . 0 4 8 9 4 3 } , { ¨ T x t “ : “ 微软杀 毒“ . “ T V p e “ : “ A S ” , ” S k ” : “ A S 5 “ , ”
输 入 ,同 时也 是引 导用 户 搜索 的工 具 ,尤 其是 对于 搜索 意 图不 是 很 明确 的用 户 。既 然是 引 导用 户 的工具 ,那 么 它就 可 以应 用于 其 他 的 网 站 和 应 用 了 。 最典 型 的 就 是 各 大 中小 网站 的 站 内搜 索 , 可 以借 用 搜 索 引擎 提示 的 自动 提 示服 务 来提 高 网站 用 户 的体 验 。
A S n , i i S k ” : AS I “ , “ H C S ” : 0 . 3 2 1 3 9 5 } , { ¨ T x t “ : “微 软 中 国 ” , “ T v p e “ : “ A S ” , ”
S k ” : ” A S 2 “ , “ H C S “ : 0 . 3 9 5 8 8 6 } , { l I T x t ” : “微 软 杀 毒 软 件 ” , “ T v p e “ : “ A S “ , S k ” : ” A S 3 I I I I H C S “ : 0 . 0 5 3 1 7 9 } , { ¨ T x t ” : ”微 软 官 网 ” , ” T v p e ” : “ AS “ , “ S k H = I l
JQERY AUTOCOMPLENT类似百度GOOLE搜索功能

利用JQUERY AUTOCOMPLENT 实现类似百度和GOOLE 搜索地功能例子:JSP :<%@page language="java"import="java.util.*"pageEncoding="UTF-8"%> <%String path = request.getContextPath();String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServ erPort()+path+"/";%><!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma"content="no-cache"><meta http-equiv="cache-control"content="no-cache"><meta http-equiv="expires"content="0"><meta http-equiv="keywords"content="keyword1,keyword2,keyword3"> <meta http-equiv="description"content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--><script type="text/javascript"src="js/jquery.js"></script><script type='text/javascript'src='js/jquery.autocomplete.js'></script><link rel="stylesheet"type="text/css"href="js/jquery.autocomplete.css"/><script language="javascript"type="text/javascript">$(document).ready((function () {function format(mail) {return ;}$("#txtUser").autocomplete("test_test.action",{multiple: true,dataType: "json",multipleSeparator:"",parse: function(data) {return $.map(data, function(row) {return {data: row,value: ,result: }});},formatItem: function(item) {return format(item);}}).result(function(e, item){$("#content").append("<p>selected " + format(item) + "</p>");});}));</script></head><body><div>省份:<input id="txtProvince"type="text"/>TEST:<input id="txtUser"type="text"/></div></body></html>后台ACTIONpublic class Test extends ActionSupport {private String q;public String test() throws Exception{JSONObject jot = new JSONObject();JSONArray jsonArray = new JSONArray();System.out.println(q);DateaBaceConnection dbc = new DateaBaceConnection();String hql = "select id,name from user where name like ?";Connection con = dbc.getConnection();System.out.println(dbc);PreparedStatement pst = con.prepareStatement(hql);pst.setString(1, "%"+ q +"%");ResultSet rs = pst.executeQuery();while(rs.next()){ System.out.println("+++++++++++++++++++++++");System.out.println("====================="+rs.getInt(1));JSONObject jo = new JSONObject();jo.put("id", rs.getInt(1));jo.put("name", rs.getString(2));jsonArray.add(jo);}jot.put("array", jsonArray);System.err.println(jsonArray.size());HttpServletResponse r = ServletActionContext.getResponse();r.setContentType("text/html;charset=UTF-8");PrintWriter out = r.getWriter();out.print(jsonArray);out.flush();out.close();return null;}public String getQ() {return q;}public void setQ(String q) {this.q = q;}}JQUERY AUTOCOMPLENT 提交地参数为qACTION 返回必须为JSON对象。
仿百度的输入框自动提示

今天在项目中碰到一个需求,就是在input输入框中录入数据时(名字),假如敲入了一部分,在数据库中存在已有的姓名的前缀与之匹配,就弹出一个 googl e页面那种效果的下拉框,把相关的姓名列出来供他选择。
可以用箭头上下选择,也可以用鼠标选择。
这样可以提高录入的效率。
输入框的布局如下:最终的效果如下:表单中输入框的html代码为:<tr><td>发件人</td><td><input type="text" name="sendername" id="sendername" value="" /></td></tr>为了在输入一些内容时,能够显示出那个选择框,我们要建立一个div,初始时不可见,当需要时就显示出来,并且将它移动到正确的位置。
这个div采用的定位为绝对定位,这样就可以在整个页面用left和top来定位了,z-index为99,这样就可以盖住下面的东西。
选择框的div为:<div id="helper" class="gac_m" style="visibility:hidden;" width="100%" ></div>gac_m的css定义为:.gac_m {background:white none repeat scroll 0 0;border:1px solid black;cursor:default;font-size:13px;line-height:17px;margin:0;position:absolute;z-index:99;width:100px;left:10px;top:10px;}当需要显示时,我们需要将id为helper的div移动到正确的位置,这个位置就是input输入框的正下方,left即为input的相对页面左边的位移,top即为inp ut相对页面上边的位移加上input本身的高度。
php+ajax做仿百度搜索下拉自动提示框(2)

php+ajax做仿百度搜索下拉自动提示框(2)php+ajax做仿百度搜索下拉自动提示框--CREATE TABLE IF NOT EXISTS `countries` (`id` int(6) NOT NULL auto_increment,`value` varchar(250) NOT NULL default '',PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=243 ;---- 转存表中的数据 `countries`--INSERT INTO `countries` (`id`, `value`) VALUES(1, 'Afghanistan'),(2, 'Aringland Islands'),(3, 'Albania'),(4, 'Algeria'),(5, 'American Samoa'),(6, 'Andorra'),(7, 'Angola'),(8, 'Anguilla'),(9, 'Antarctica'),(10, 'Antigua and Barbuda'),(11, 'Argentina'),(12, 'Armenia'),(13, 'Aruba'),(14, 'Australia'),(15, 'Austria'),(16, 'Azerbaijan'),(17, 'Bahamas'),(18, 'Bahrain'),(19, 'Bangladesh'),(20, 'Barbados'),(21, 'Belarus'),(22, 'Belgium'),(23, 'Belize'),(24, 'Benin'),(25, 'Bermuda'),(26, 'Bhutan'),(27, 'Bolivia'),(28, 'Bosnia and Herzegovina'), (29, 'Botswana'),(30, 'Bouvet Island'),(31, 'Brazil'),(32, 'British Indian Ocean territory'), (33, 'Brunei Darussalam'),(34, 'Bulgaria'),(35, 'Burkina Faso'),(36, 'Burundi'),(37, 'Cambodia'),(38, 'Cameroon'),(39, 'Canada'),(40, 'Cape Verde'),(41, 'Cayman Islands'),(42, 'Central African Republic'), (43, 'Chad'),(44, 'Chile'),(45, 'China'),(46, 'Christmas Island'),(47, 'Cocos (Keeling) Islands'), (48, 'Colombia'),(49, 'Comoros'),(50, 'Congo'),(51, 'Congo'),(52, ' Democratic Republic'), (53, 'Cook Islands'),(54, 'Costa Rica'),(55, 'Ivory Coast (Ivory Coast)'), (56, 'Croatia (Hrvatska)'), (57, 'Cuba'),(58, 'Cyprus'),(59, 'Czech Republic'),(60, 'Denmark'),(61, 'Djibouti'),(62, 'Dominica'),(63, 'Dominican Republic'), (64, 'East Timor'),(65, 'Ecuador'),(66, 'Egypt'),(67, 'El Salvador'),(68, 'Equatorial Guinea'), (69, 'Eritrea'),(70, 'Estonia'),(71, 'Ethiopia'),(72, 'Falkland Islands'), (73, 'Faroe Islands'),(74, 'Fiji'),(75, 'Finland'),(76, 'France'),(77, 'French Guiana'),(78, 'French Polynesia'),(79, 'French Southern Territories'), (80, 'Gabon'),(81, 'Gambia'),(82, 'Georgia'),(83, 'Germany'),(84, 'Ghana'),(85, 'Gibraltar'),(86, 'Greece'),(87, 'Greenland'),(88, 'Grenada'),(89, 'Guadeloupe'),(90, 'Guam'),(91, 'Guatemala'),(92, 'Guinea'),(93, 'Guinea-Bissau'),(94, 'Guyana'),(95, 'Haiti'),(96, 'Heard and McDonald Islands'), (97, 'Honduras'),(98, 'Hong Kong'),(99, 'Hungary'),(100, 'Iceland'),(101, 'India'),(102, 'Indonesia'),(103, 'Iran'),(104, 'Iraq'),(105, 'Ireland'),(106, 'Israel'),(107, 'Italy'),(108, 'Jamaica'),(109, 'Japan'),(110, 'Jordan'),(111, 'Kazakhstan'),(112, 'Kenya'),(113, 'Kiribati'),(114, 'Korea (north)'),(115, 'Korea (south)'),(116, 'Kuwait'),(117, 'Kyrgyzstan'),(118, 'Lao People''s Democratic Republic'), (119, 'Latvia'),(120, 'Lebanon'),(121, 'Lesotho'),下载文档。
基于jquery的搜索框输入提示

基于jquery的搜索框输⼊提⽰仿百度与google的搜索框输⼊提⽰,⽀持键盘上下选择与⿏标点击选择。
只包含前⾯代码,后台返回数据为模拟的数据。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>搜索</title><meta name="description" content=" 内容介绍不超过100个中⽂"><meta name="keywords" content=" 内容相关关键词3-5个"><link href="index.css" rel="stylesheet" type="text/css" /><script type="text/javascript" src="jquery-1.4.3.min.js"></script></head><body><div class="gover_search"><div class="gover_search_form clearfix"><span class="search_t">关键词匹配搜索</span><input type="text" class="input_search_key" id="gover_search_key" placeholder="请输⼊关键词直接搜索" /><button type="submit" class="search_btn">搜索</button><div class="search_suggest" id="gov_search_suggest"><ul></ul></div></div></div><script type="text/javascript">//实现搜索输⼊框的输⼊提⽰js类function oSearchSuggest(searchFuc){var input = $('#gover_search_key');var suggestWrap = $('#gov_search_suggest');var key = "";var init = function(){input.bind('keyup',sendKeyWord);input.bind('blur',function(){setTimeout(hideSuggest,100);})}var hideSuggest = function(){suggestWrap.hide();}//发送请求,根据关键字到后台查询var sendKeyWord = function(event){//键盘选择下拉项if(suggestWrap.css('display')=='block'&&event.keyCode == 38||event.keyCode == 40){var current = suggestWrap.find('li.hover');if(event.keyCode == 38){if(current.length>0){if(current.length>0){var prevLi = current.removeClass('hover').prev();if(prevLi.length>0){prevLi.addClass('hover');input.val(prevLi.html());}}else{var last = suggestWrap.find('li:last');last.addClass('hover');input.val(last.html());}}else if(event.keyCode == 40){if(current.length>0){var nextLi = current.removeClass('hover').next();if(nextLi.length>0){nextLi.addClass('hover');input.val(nextLi.html());}}else{var first = suggestWrap.find('li:first');first.addClass('hover');input.val(first.html());}}//输⼊字符}else{var valText = $.trim(input.val());if(valText ==''||valText==key){return;}searchFuc(valText);key = valText;}}//请求返回后,执⾏数据展⽰this.dataDisplay = function(data){if(data.length<=0){suggestWrap.hide();return;}//往搜索框下拉建议显⽰栏中添加条⽬并显⽰var li;var tmpFrag = document.createDocumentFragment(); suggestWrap.find('ul').html('');for(var i=0; i<data.length; i++){li = document.createElement('LI');li.innerHTML = data[i];tmpFrag.appendChild(li);}suggestWrap.find('ul').append(tmpFrag);suggestWrap.show();//为下拉选项绑定⿏标事件suggestWrap.find('li').hover(function(){suggestWrap.find('li').removeClass('hover');$(this).addClass('hover');},function(){$(this).removeClass('hover');}).bind('click',function(){input.val(this.innerHTML);suggestWrap.hide();index.css。
使用jQuery模拟Google的自动提示效果

使用jQuery模拟Google的自动提示效果注意:1、本功能使用SqlServler2000中的示例数据库Northwind,请打SP3或SP4补丁;2、请下载jQuery组件,河西FTP中有下载;3、本功能实现类似Google自动提示的效果,通过ajax引擎从服务器获取,返回XML数据;4、本示例程序没考虑性能问题;5、不支持Firefox浏览器,因为该浏览器没有propertychange事件。
步骤:1、创建一个名为GoogleServlet的Servlet,负责从数据库中读取数据并生成XML格式的数据。
package com.aptech.servlet;import java.io.IOException;import java.io.PrintWriter;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class GoogleServlet extends HttpServlet {public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/xml;charset=utf-8");request.setCharacterEncoding("utf-8");PrintWriter out = response.getWriter();String key = request.getParameter("key");try {Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");Connection conn =DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;DatabaseName= northwind", "sa", "");PreparedStatement pstmt = conn.prepareStatement("select shipname,count(shipname) as c from [orders] where shipname like ? group by shipname");pstmt.setString(1, key + "%");ResultSet rs = pstmt.executeQuery();StringBuilder xml = new StringBuilder();xml.append("<results>");if(rs != null){while(rs.next()){xml.append("<result key=""" + rs.getString(1) + """ count=""" + rs.getInt(2) + """></result>");}}xml.append("</results>");rs.close();pstmt.close();conn.close();out.print(xml.toString());} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}out.flush();out.close();}}2、定义一个名为google.html的HTML文件,负责动态生成自动提示的效果。
(实现类似GOOGLE搜索框的自动提示功能+)AJAXTOOLKITAUTOCOMPLETEEXTENDER+用法详解

2. AutoCompleteExtender 的效果(功能)
如下图所示, 当在文本框中录入1 时, 所有包括1 的串都被显示出来, 当录入123 的时候, 包括123 的串被显示出来, 在这个下拉列表中单击选 中某一项, 则文本框的值改变为选中的项的值. (当选中某项时需要触发事件, 或想使用键值对的话, 请参阅我的另一篇文章ajaxToolkit:AutoCompleteExtender 的触发选择事件以及JSON序列化和使用键值对. 值得注意的是: 下拉列表中的项与文本框中录入的内容的关联的规则是自己定义的, 例如, 示例图中, 录入1时, 凡是包括1的串都被显示了出来, 无论1 在这个串的什么位置都可以, 但是可能你希望只显示以1 开头的串, 你只需要修改一下服务方法的实现即可, 稍eteExtender
既然名为Extender, 就说明它是一个扩展控件, 它必须依赖于别人而存在-----这个别人指的是文本框. 所以,
首先要有一个宿主文本框:
<asp:TextBox ID=&uot;txt1&uot; runat=&uot;server&uot;></asp:Tex
指令即可. 例如, 我的示例页面的指令:
<%@ Register Assembly=&uot;AjaxControlToolkit&uot; Namespace=&uot;AjaxControlToolkit&uot;
TagPrefix=&uot;ajaxToolkit&uot; %>
并不多, 于是我有了充分的理由再写一篇关于这个控件的详细介绍.
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
完善了以下功能:1,中文传参,参数名称没有改动,仍是默认的q:String toPage = request.getParameter("q");page= new String(toPage.getBytes("ISO-8859-1"), "UTF-8");2,支持上下翻页,并且文本框的值即时改动,和google、百度一个效果3,鼠标事件,鼠标离开时层失去焦点,不锁定提示层4,已经匹配的字用细体显示,未匹配的用黑体显示,5,,增加提交之前的验证,比入输入中文时候需要敲空格,则输入之前不传参,还有一些细微的完善,此处不赘述,需注意的是,若需实现本人完善的效果,需要另存本人的jquery.autocomplete.js文件,以及jquery.autocomplete.css文件,另外几个文件,请到官网下载:http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/jquery.jsp:<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""/TR/html4/loose.dtd"><html><head><script src="js/jquery-latest.js"></script><link rel="stylesheet" href="js/jquery.autocomplete.css" type="text/css" /><script type="text/javascript" src="js/jquery.bgiframe.min.js"></script><script type="text/javascript" src="js/jquery.dimensions.js"></script><script type="text/javascript" src="js/jquery.autocomplete.js"></script><script>$(document).ready(function(){$("#example").autocomplete("Jquery");});</script></head><body>API Reference: <input id="example" size=40/> (try "C" or "E")</body></html>jquery.autocomplete.js代码如下:/*** 此js为本人修改完善版,以下功能* ---李小朋2:45 2010-10-31**/;(function($) {$.fn.extend({autocomplete: function(urlOrData, options) {var isUrl = typeof urlOrData == "string";options = $.extend({}, $.Autocompleter.defaults, {url: isUrl ? urlOrData : null,data: isUrl ? null : urlOrData,delay: isUrl ? $.Autocompleter.defaults.delay : 10,max: options && !options.scroll ? 10 : 150}, options);// if highlight is set to false, replace it with a do-nothing functionoptions.highlight = options.highlight || function(value) { return value; };// if the formatMatch option is not specified, then use formatItem for backwards compatibility options.formatMatch = options.formatMatch || options.formatItem;return this.each(function() {new $.Autocompleter(this, options);});},result: function(handler) {return this.bind("result", handler);},search: function(handler) {return this.trigger("search", [handler]);},flushCache: function() {return this.trigger("flushCache");},setOptions: function(options){return this.trigger("setOptions", [options]);},unautocomplete: function() {return this.trigger("unautocomplete");}});$.Autocompleter = function(input, options) {var KEY = {UP: 38,DOWN: 40,DEL: 46,TAB: 9,RETURN: 13,ESC: 27,COMMA: 188,PAGEUP: 33,PAGEDOWN: 34,BACKSPACE: 8};// Create $ object for input elementvar $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);var timeout;var previousValue = "";var cache = $.Autocompleter.Cache(options);var hasFocus = 0;var lastKeyPressCode;var config = {mouseDownOnSelect: false};var select = $.Autocompleter.Select(options, input, selectCurrent, config);var blockSubmit;// prevent form submit in opera when selecting with return key$.browser.opera && $(input.form).bind("submit.autocomplete", function() {if (blockSubmit) {blockSubmit = false;return false;}});// only opera doesn't trigger keydown multiple times while pressed, others don't work withkeypress at all$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) { // track last key pressedlastKeyPressCode = event.keyCode;switch(event.keyCode) {case KEY.UP:event.preventDefault();if ( select.visible() ) {select.prev();} else {onChange(0, true);}break;case KEY.DOWN:event.preventDefault();if ( select.visible() ) {select.next();} else {onChange(0, true);}break;case KEY.PAGEUP:event.preventDefault();if ( select.visible() ) {select.pageUp();} else {onChange(0, true);}break;case KEY.PAGEDOWN:event.preventDefault();if ( select.visible() ) {select.pageDown();} else {onChange(0, true);}break;// matches also semicoloncase options.multiple && $.trim(options.multipleSeparator) == "," && MA: case KEY.TAB:case KEY.RETURN:if( selectCurrent() ) {// stop default to prevent a form submit, Opera needs special handlingevent.preventDefault();blockSubmit = true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout = setTimeout(onChange, options.delay);break;}}).focus(function(){// track whether the field has focus, we shouldn't process any// results if the field no longer has focushasFocus++;}).blur(function() {hasFocus = 0;if (!config.mouseDownOnSelect) {hideResults();}}).click(function() {// show select when clicking in a focused fieldif ( hasFocus++ > 1 && !select.visible() ) {onChange(0, true);}}).bind("search", function() {// TODO why not just specifying both arguments?var fn = (arguments.length > 1) ? arguments[1] : null;function findValueCallback(q, data) {var result;if( data && data.length ) {for (var i=0; i < data.length; i++) {if( data[i].result.toLowerCase() == q.toLowerCase() ) {result = data[i];break;}}}if( typeof fn == "function" ) fn(result);else $input.trigger("result", result && [result.data, result.value]);}$.each(trimWords($input.val()), function(i, value) {request(value, findValueCallback, findValueCallback);});}).bind("flushCache", function() {cache.flush();}).bind("setOptions", function() {$.extend(options, arguments[1]);// if we've updated the data, repopulateif ( "data" in arguments[1] )cache.populate();}).bind("unautocomplete", function() {select.unbind();$input.unbind();$(input.form).unbind(".autocomplete");});function selectCurrent() {var selected = select.selected();if( !selected )return false;var v = selected.result;previousValue = v;if ( options.multiple ) {var words = trimWords($input.val());if ( words.length > 1 ) {v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;}v += options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result", [selected.data, selected.value]);}function onChange(crap, skipPrevCheck) {if( lastKeyPressCode == KEY.DEL ) {select.hide();return;}var currentValue = $input.val();if ( !skipPrevCheck && currentValue == previousValue ) return;previousValue = currentValue;currentValue = lastWord(currentValue);if ($.trim(currentValue).length >= options.minChars) { $input.addClass(options.loadingClass);if (!options.matchCase)currentValue = currentValue.toLowerCase(); request(currentValue, receiveData, hideResultsNow); } else {stopLoading();select.hide();}};function trimWords(value) {if ( !value ) {return [""];}var words = value.split( options.multipleSeparator ); var result = [];$.each(words, function(i, value) {if ( $.trim(value) )result[i] = $.trim(value);});return result;}function lastWord(value) {if ( !options.multiple )var words = trimWords(value);return words[words.length - 1];}// fills in the input box w/the first match (assumed to be the best match)// q: the term entered// sValue: the first matching resultfunction autoFill(q, sValue){// autofill in the complete box w/the first match as long as the user hasn't entered in more data// if the last user key pressed was backspace, don't autofillif( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {// fill in the value (keep the case the user has typed)$input.val($input.val() + sValue.substring(lastWord(previousValue).length));// select the portion of the value not typed by the user (so the next character will erase) $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);}};function hideResults() {clearTimeout(timeout);timeout = setTimeout(hideResultsNow, 200);};function hideResultsNow() {var wasVisible = select.visible();select.hide();clearTimeout(timeout);stopLoading();if (options.mustMatch) {// call search and run callback$input.search(function (result){// if no value found, clear the input boxif( !result ) {if (options.multiple) {var words = trimWords($input.val()).slice(0, -1);$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );}else$input.val( "" );}});}if (wasVisible)// position cursor at end of input field$.Autocompleter.Selection(input, input.value.length, input.value.length); };function receiveData(q, data) {if ( data && data.length && hasFocus ) {stopLoading();select.display(data, q);autoFill(q, data[0].value);select.show();} else {hideResultsNow();}};function request(term, success, failure) {if (!options.matchCase)term = term.toLowerCase();var data = cache.load(term);// recieve the cached dataif (data && data.length) {success(term, data);// if an AJAX url has been supplied, try loading the data now} else if( (typeof options.url == "string") && (options.url.length > 0) ){var extraParams = {timestamp: +new Date()};$.each(options.extraParams, function(key, param) {extraParams[key] = typeof param == "function" ? param() : param; });$.ajax({// try to leverage ajaxQueue plugin to abort previous requestsmode: "abort",// limit abortion to this inputport: "autocomplete" + ,dataType: options.dataType,url: options.url,data: $.extend({q: lastWord(term),limit: options.max}, extraParams),success: function(data) {var parsed = options.parse && options.parse(data) || parse(data);cache.add(term, parsed);success(term, parsed);}});} else {// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful matchselect.emptyList();failure(term);}};function parse(data) {var parsed = [];var rows = data.split("&");for (var i=0; i < rows.length; i++) {var row = $.trim(rows[i]);if (row) {row = row.split("|");parsed[parsed.length] = {data: row,value: row[0],result: options.formatResult && options.formatResult(row, row[0]) || row[0]};}}return parsed;};function stopLoading() {$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults = {inputClass: "ac_input",resultsClass: "ac_results",loadingClass: "ac_loading",minChars: 1,delay: 400,matchCase: false,matchSubset: true,matchContains: false,cacheLength: 10,max: 10,mustMatch: false,extraParams: {},selectFirst: false,formatItem: function(row) {return row[0]; },formatMatch: null,autoFill: false,width: 0,multiple: false,multipleSeparator: ", ",highlight: function(value, term) {return value.replace($.trim(term), "<span style='font-weight:Lighter;' >"+$.trim(term)+"</span>");},scroll: false,scrollHeight: 180};$.Autocompleter.Cache = function(options) {var data = {};var length = 0;function matchSubset(s, sub) {if (!options.matchCase)s = s.toLowerCase();var i = s.indexOf(sub);if (options.matchContains == "word"){i = s.toLowerCase().search("\\b" + sub.toLowerCase());}if (i == -1) return false;return i == 0 || options.matchContains;};function add(q, value) {if (length > options.cacheLength){flush();}if (!data[q]){length++;}data[q] = value;}function populate(){if( !options.data ) return false;// track the matchesvar stMatchSets = {},nullData = 0;// no url was specified, we need to adjust the cache length to make sure it fits the local data storeif( !options.url ) options.cacheLength = 1;// track all options for minChars = 0stMatchSets[""] = [];// loop through the array and create a lookup structurefor ( var i = 0, ol = options.data.length; i < ol; i++ ) {var rawValue = options.data[i];// if rawValue is a string, make an array otherwise just reference the arrayrawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;var value = options.formatMatch(rawValue, i+1, options.data.length);if ( value === false )continue;var firstChar = value.charAt(0).toLowerCase();// if no lookup array for this character exists, look it up nowif( !stMatchSets[firstChar] )stMatchSets[firstChar] = [];// if the match is a stringvar row = {value: value,data: rawValue,result: options.formatResult && options.formatResult(rawValue) || value};// push the current match into the set liststMatchSets[firstChar].push(row);// keep track of minChars zero itemsif ( nullData++ < options.max ) {stMatchSets[""].push(row);}};// add the data items to the cache$.each(stMatchSets, function(i, value) {// increase the cache sizeoptions.cacheLength++;// add to the cacheadd(i, value);});}// populate any existing datasetTimeout(populate, 25);function flush(){data = {};length = 0;}return {flush: flush,add: add,populate: populate,load: function(q) {if (!options.cacheLength || !length)return null;/** if dealing w/local data and matchContains than we must make sure * to loop through all the data collections looking for matches*/if( !options.url && options.matchContains ){// track all matchesvar csub = [];// loop through all the data grids for matchesfor( var k in data ){// don't search through the stMatchSets[""] (minChars: 0) cache// this prevents duplicatesif( k.length > 0 ){var c = data[k];$.each(c, function(i, x) {// if we've got a match, add it to the arrayif (matchSubset(x.value, q)) {csub.push(x);}});}}return csub;} else// if the exact item exists, use itif (data[q]){return data[q];} elseif (options.matchSubset) {for (var i = q.length - 1; i >= options.minChars; i--) {var c = data[q.substr(0, i)];if (c) {var csub = [];$.each(c, function(i, x) {if (matchSubset(x.value, q)) {csub[csub.length] = x;}});return csub;}}}return null;}};};$.Autocompleter.Select = function (options, input, select, config) {var CLASSES = {ACTIVE: "ac_over"};var listItems,active = -1,data,term = "",needsInit = true,element,list;// Create resultsfunction init() {if (!needsInit)return;element = $("<div/>").hide().addClass(options.resultsClass).css("position", "absolute").appendTo(document.body);list = $("<ul/>").appendTo(element).mouseover( function(event) {if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event) {$(target(event)).addClass(CLASSES.ACTIVE);select();// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focusinput.focus();return false;}).mouseout(function() {$("li").removeClass(CLASSES.ACTIVE);active =-1;}).mousedown(function() {config.mouseDownOnSelect = true;}).mouseup(function() {config.mouseDownOnSelect = false;});if( options.width > 0 )element.css("width", options.width);needsInit = false;}function target(event) {var element = event.target;while(element && element.tagName != "LI")element = element.parentNode;// more fun with IE, sometimes event.target is empty, just ignore it thenif(!element)return [];return element;}function moveSelect(step) {listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);if(options.scroll) {var offset = 0;listItems.slice(0, active).each(function() {offset += this.offsetHeight;});if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) { list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());} else if(offset < list.scrollTop()) {list.scrollTop(offset);}}};function movePosition(step) {active += step;if (active < 0) {active = listItems.size() - 1;} else if (active >= listItems.size()) {active = 0;}}function limitNumberOfItems(available) {return options.max && options.max < available? options.max: available;}function fillList() {list.empty();var max = limitNumberOfItems(data.length);for (var i=0; i < max; i++) {if (!data[i])continue;var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);if ( formatted === false )continue;var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];$.data(li, "ac_data", data[i]);}listItems = list.find("li");if ( options.selectFirst ) {listItems.slice(0, 1).addClass(CLASSES.ACTIVE);active = 0;}// apply bgiframe if availableif ( $.fn.bgiframe )list.bgiframe();}return {display: function(d, q) {init();data = d;term = q;fillList();},next: function() {if(active+1==data.length){$(input).val(term);$("li").removeClass(CLASSES.ACTIVE);active=-1;}else{moveSelect(1);$(input).val($(data[active]).val());}},prev: function() {if(active-1==-1){$(input).val(term);$("li").removeClass(CLASSES.ACTIVE);active=data.length;}else{moveSelect(-1);$(input).val($(data[active]).val());}},pageUp: function() {if (active != 0 && active - 8 < 0) {moveSelect( -active );} else {moveSelect(-8);}},pageDown: function() {if (active != listItems.size() - 1 && active + 8 > listItems.size()) {moveSelect( listItems.size() - 1 - active );} else {moveSelect(8);}},hide: function() {element && element.hide();listItems && listItems.removeClass(CLASSES.ACTIVE);active = -1;},visible : function() {return element && element.is(":visible");},current: function() {return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);},show: function() {var offset = $(input).offset();element.css({width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),top: offset.top + input.offsetHeight,left: offset.left}).show();if(options.scroll) {list.scrollTop(0);list.css({maxHeight: options.scrollHeight,overflow: 'auto'});if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {var listHeight = 0;listItems.each(function() {listHeight += this.offsetHeight;});var scrollbarsVisible = listHeight > options.scrollHeight;list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );if (!scrollbarsVisible) {// IE doesn't recalculate width when scrollbar disappearslistItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );}}}},selected: function() {var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected && selected.length && $.data(selected[0], "ac_data");},emptyList: function (){list && list.empty();},unbind: function() {element && element.remove();}};};$.Autocompleter.Selection = function(field, start, end) {if( field.createT extRange ){var selRange = field.createTextRange();selRange.collapse(true);selRange.moveStart("character", start);selRange.moveEnd("character", end);selRange.select();} else if( field.setSelectionRange ){field.setSelectionRange(start, end);} else {if( field.selectionStart ){field.selectionStart = start;field.selectionEnd = end;}}field.focus();};})(jQuery);另外附一个样式文件,jquery.autocomplete.css:* {margin: 0px; }/***提示层的样式,除颜色及字体、边框等,其他样式请勿随意更改**/.ac_results {padding: 0px;border: 1px solid #CCCCCC;background-color: white;overflow: hidden;z-index: 99999;}.ac_results ul {width: 100%;list-style-position: outside;list-style: none;padding: 0;margin: 0;}/*提示内容的样式*/.ac_results li {margin: 0px;padding: 2px 5px;cursor: default;display: block;font-size:17px;color:#333333;line-height: 19px;font-weight:Bold;overflow: hidden;}/*加载时的样式,一个小loading图片,大家可以随便改*/.ac_loading {background: white url('images/loading.gif') right center no-repeat; }/*提示层内奇数行的样式,比如隔一行显示的背景色不同等*/.ac_odd {background-color: #FFFFFF;}/*鼠标放上去时候的样式,此处仅仅改背景色*/.ac_over {background-color: #DEE4E4;}。