ice world

          There is nothing too difficult if you put your heart into it.
          posts - 104, comments - 103, trackbacks - 0, articles - 0

          高仿Google Suggest & Baidu Suggest

          Posted on 2011-04-24 03:41 IceWee 閱讀(895) 評論(0)  編輯  收藏 所屬分類: Javascript

          經(jīng)常用谷歌百度的人會覺得他們自動提示下拉框很酷,而且用來起很方便。最近由于業(yè)務需求,我們也需要這樣的功能,網(wǎng)絡上搜刮了一下,但卻遇不到自己滿意的,于是決定取長補短,自己重構。由于平常很少寫類似控件或小工具的腳本,頂多寫點簡單的校驗腳本,所以寫了這個東東花費了我3天時間,當然3天也不全是一直撲到它身上,畢竟還有其他的工作,通過這次練習,自己對protype的熟悉又更近了一步。

          這個版本自己還算滿意,可自定義的參數(shù)也開放了不少,主要是為用著方便著想嘛!沒有引用外部css類,而是全寫在腳本里,畢竟一個下拉提示框而已,并不是什么復雜的控件,也沒必要再單獨弄個css文件。

          支持動態(tài)數(shù)據(jù)和靜態(tài)數(shù)據(jù)兩種方式,二者擇一,動態(tài)數(shù)據(jù)通過傳遞url和參數(shù)名,靜態(tài)數(shù)據(jù)通過傳遞數(shù)組,如果都傳遞則根據(jù)指定的是否是用動態(tài)數(shù)據(jù)參數(shù)來決定,如果沒有設置該參數(shù)則使用靜態(tài)數(shù)據(jù)。語言描述比較蒼白,代碼不多,但我這水平較淺,寫出來也費勁心思,呵呵,見笑!下面將HTML和JS代碼貼出:

          下拉框外觀完全仿照谷歌樣式,包含邊框以及選中項的背景色。至于關鍵字樣式是仿照百度做的,谷歌關鍵字并沒有處理,大家可以打開谷歌和百度比較一下區(qū)別。

          界面截圖:


          Google.html

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

          <HTML>
          <HEAD>
          <TITLE>高仿Google Suggest & Baidu Suggest</TITLE>
          <META http-equiv="Content-Type" content="text/html; charset=GBK">
          <script type="text/javascript" src="google.suggest.js"></script>
          <script type="text/javascript">
          <!--
          var stringArray = new Array('java', 'JAVA游戲', 'java下載', 'javascript', 'javaeye', 'JAVA教程', 'java游戲下載', 'javascript教程', 'JAVA虛擬機', 'java正則表達式',
          '77元廉租房', '77元特惠房', '77元大床房', '77元特惠大床房', '77元 7天', '77元特惠房預訂專區(qū)', '7天77元', '7天連鎖酒店77元',
          '程序員', '程序員之家', '程序員考試', '程序員面試寶典', '程序員工資', '程序員的老婆是誰', '程序員論壇', '程序員修煉之道', '程序員雜志', '程序員招聘');
          var objectArray = new Array();
          var url = 'http://localhost:8080/google.suggest/servlet/getData?dataType=string'; // object or string

          function initObjectArray() {
          var id;
          var name;
          for (var i = 0; i < stringArray.length; ++i) {
          id
          = i+1;
          name
          = stringArray[i];
          objectArray[i]
          = {id: id, name: name};
          }
          }

          /**
          * 回調(diào)函數(shù)
          *
          * @param {Object} id 當為字符串數(shù)組時,沒有值
          * @param {Object} name
          */
          function callback(id, name) {
          document.getElementById(
          'span_id_value').innerHTML = id;
          document.getElementById(
          'span_name_value').innerHTML = name;
          }

          window.onload
          = function() {
          var input = document.getElementById('search');
          input.blur();
          // FireFox想聚焦必須先失去焦點
          input.focus();
          initObjectArray();

          var data = {
          input: input,
          // 必需參數(shù),可為輸入框ID或者輸入框?qū)ο?/span>
          isDynamicData: false, // 可選參數(shù),默認false,不指定則自動判斷給定的數(shù)組參數(shù)與url,如果指定了動態(tài)或靜態(tài)數(shù)據(jù)方式則相應參數(shù)為必填,如指定了true,則url必須有效,指定了false,則數(shù)組不能為空
          isObjectArray: false , // 可選參數(shù),默認false,使用的是否是對象數(shù)組或字符串數(shù)組,如果為對象數(shù)組要求屬性名為id和name,如果不指定則默認使用字符串數(shù)組
          dataArray: stringArray, // 與url二選一,字符串數(shù)組,如果數(shù)組內(nèi)容不為空,同時又指定了url,則優(yōu)先使用數(shù)組
          url: url, // 與dataArray二選一,ajax動態(tài)獲取數(shù)據(jù)的url
          paramName: 'keywords', // 如果動態(tài)獲取數(shù)據(jù)為必需參數(shù),否則為可選參數(shù)
          maxShowRows: 20, // 可選參數(shù),下拉框最大顯示行數(shù),超出該值的數(shù)據(jù)將不被顯示,默認值為30
          showText: 'Google Search', // 可選參數(shù),默認顯示在輸入框中的文字,一般用于提示用戶,如果不指定則默認為“”
          showTextOffsetLeft: 7, // 可選參數(shù) ,下拉列表文字內(nèi)容與左側(cè)的空白距離,默認值為0
          showTextColor: '', // 可選參數(shù),默認顯示在輸入框中的文字的顏色,默認顏色為灰色,值為“#999999”
          showTextFontStyle: '', // 可選參數(shù),默認顯示在輸入框中的文字的樣式, 默認樣式為斜體,值為“italic”
          focusItemBgColor: '', // 可選參數(shù),鼠標停留(mouseover)下拉框的背景色,同Google,值為“#D5E2FF”
          blurItemBgColor: '', // 可選參數(shù),鼠標劃過(mouseout)下拉框的背景色,默認顏色為白色,值為 “#FFFFFF”
          suggestBorderColorLT: '', // 可選參數(shù), 下拉框左上的邊框顏色,同Google,值為“#A2BFF0”, LT 含義為 left和top
          suggestBorderColorRB: '', // 可選參數(shù), 下拉框右下的邊框顏色,同Google,值為“#558BE3”, RB含義為right和bottom
          itemFontSize: '', // 可選參數(shù),下拉框每一行的字體大小,如果未指定而且輸入框也沒設置字體大小則默認值為12pt,如果未指定,但輸入框指定了字體大小,則自動使用輸入框字體大小
          isSortData: '', // 可選參數(shù),是否將數(shù)據(jù)進行排序顯示,默認不排序
          callback: callback, // 可選參數(shù),回調(diào)函數(shù),參數(shù)為id和name,如果為對象數(shù)組ID有值,當用戶鼠標點擊或者按回車選擇后觸發(fā)該函數(shù)
          isCaseSensitive: true // 可選參數(shù),是否忽略查詢英文字母大小寫,默認為false,即不忽略,靜態(tài)數(shù)據(jù)有效,動態(tài)數(shù)據(jù)該參數(shù)無效,而是由服務端處理邏輯決定
          }
          new googleSuggest(data).go();
          }
          //-->
          </script>
          <style type="text/css">
          <!--
          #search
          {
          background
          : #FFFFFF;
          border-width
          : 1px;
          border-style
          : solid;
          border-color
          : #CCCCCC #999999 #999999 #CCCCCC;
          font-size
          : 14pt;
          margin
          : 0px;
          padding
          : 5px 8px 0px 3px;
          color
          : #000000;
          height
          : 30px;
          }

          .lsbb
          {
          background
          : #eee;
          border
          : solid 1px;
          border-color
          : #ccc #999 #999 #ccc;
          height
          : 30px;
          display
          : inline-block;
          }

          .lsb
          {
          background
          : url('nav_logo66.png') bottom;
          border
          : none;
          color
          : #000;
          cursor
          : pointer;
          height
          : 30px;
          margin
          : 0;
          outline
          : 0;
          padding
          : 0 6px;
          width
          : auto;
          overflow
          : visible;
          font
          : 15px arial, sans-serif;
          vertical-align
          : top;
          }
          //-->
          </style>
          </HEAD>
          <BODY style="margin: 0; background-color: #FFFFFF; color: #000000;">
          <table cellSpacing="0" cellPadding="0" width="100%" height="24">
          <tr>
          <td>
          id:[
          <span id="span_id_value" style="text-align: center; width: 20px;"></span>]&nbsp;&nbsp;name:[<span id="span_name_value" style="text-align: center; width: 150px;"></span>]
          </td>
          <td></td>
          <td>
          <DIV style="width: 100%; padding-top: 1px !important; text-align: right;">
          <span style="font-style: italic; color: #0000CC; padding-right: 5px;">高仿Google Suggest & Baidu Suggest</span>
          </DIV>
          </td>
          </tr>
          </table>
          <DIV style="position: absolute; right: 0px; width: 100%; top: 24px; height: 0; border-top: 1px solid #c9d7f1;"></DIV>
          <CENTER>
          <BR />
          <DIV><IMG id="logo" title="Google" border="0" alt="Google" src="logo_cn.png" width="276" height="110"><BR /><BR /></DIV>
          <TABLE cellSpacing="0" cellPadding="0">
          <TR vAlign="top">
          <TD align="center">
          <INPUT id="search" title="Google 搜索" size="57" /><BR /><BR /><BR />
          <SPAN class="ds">
          <SPAN class="lsbb"><INPUT class="lsb" value="Google 搜索" type="button" /></SPAN>
          </SPAN>
          <SPAN class="ds">
          <SPAN class="lsbb"><INPUT class="lsb" value="&nbsp;手氣不錯&nbsp;" type="button" /></SPAN>
          </SPAN>
          </TD>
          </TR>
          </TABLE>
          <DIV style="font-size: 83%; min-height: 3.5em;"><BR>
          <DIV id="als"><FONT id="addlang" size="-1">請輸入以下關鍵字進行測試:java 77元 程序員</FONT><BR /><BR /></DIV>
          </DIV>
          <SPAN id="footer">
          <CENTER id="fctr">
          <DIV style="font-size: 10pt;">
          <DIV style="margin: 19px auto; text-align: center;" id="fll">
          <a style="display: inline-block; margin: 0 12px;" href="mailto:icewee@tom.com?subject=Google Suggest">聯(lián)系作者</a>
          <a style="display: inline-block; margin: 0 12px;" href="http://icewee.cnblogs.com" target="_blank">作者博客</a>
          </DIV>
          </DIV>
          <P style="color: rgb(118, 118, 118); font-size: 8pt;">&copy; 2011 - <A href="javascript:void(0)">Icesoft</A></P>
          </CENTER>
          </SPAN>
          </CENTER>
          </BODY>
          </HTML>


          google.suggest.js 第一部分

          /**
          * This version of Software is free for using in non-commercial applications.
          * For commercial use please contact icewee@tom.com to obtain license
          * author: IceWee
          * blog: http://icewee.cnblogs.com
          * Date: 2011-04-25 0:58:54 (Mon, 25 Apri 2011)
          */
          function googleSuggest(data) {
          this.$settings = {
          input:
          null,
          url:
          null,
          paramName:
          null,
          dataArray:
          new Array(),
          maxShowRows:
          30,
          showText:
          '',
          showTextColor:
          '#999999',
          showTextFontStyle:
          'italic',
          showTextOffsetLeft:
          0,
          focusItemBgColor:
          '#D5E2FF',
          blurItemBgColor:
          '#FFFFFF',
          suggestBorderColorLT:
          '#A2BFF0',
          suggestBorderColorRB:
          '#558BE3',
          isDynamicData:
          false,
          itemFontSize:
          '12pt',
          isSortData:
          true,
          isObjectArray:
          false,
          callback:
          null,
          isCaseSensitive:
          false
          }
          this.$isIE = true;
          this._copySettings(data);
          this.$suggest = null; // suggest div
          this.$focusItemIndex = -1;
          this.$DOWN = '40'; // keyboard keyCode down
          this.$UP = '38'; // keyboard keyCode up
          this.$ENTER = '13'; // keyboard keyCode Enter
          this.$xmlHttp = null; // ajax object
          this.$HTTP_STATE_UNINITIALIZED = 0; // xmlHttpRequest object is not be initilaized
          this.$HTTP_STATE_LOADING = 1;
          this.$HTTP_STATE_LOADED = 2;
          this.$HTTP_STATE_INTERACTIVING = 3;
          this.$HTTP_STATE_COMPLETED = 4;
          this.$HTTP_STATUS_OK = 200;
          return this;
          }

          /**
          * @desc: working now!
          */
          googleSuggest.prototype.go
          = function() {
          if (this._isCanGo()) {
          this._initSuggest();
          this._initInput();
          }
          else {
          alert(
          'initialize failed!');
          }
          };

          /**
          * @desc: copy params that user specified
          *
          * @param {Object} data
          */
          googleSuggest.prototype._copySettings
          = function(data) {
          if (typeof(data.input) == 'string')
          this.$settings.input = document.getElementById(data.input);
          else
          this.$settings.input = data.input;
          if (data.isSortData && data.isSortData == true) {
          this.$settings.isSortData = true;
          }
          else {
          this.$settings.isSortData = false;
          }
          if (data.isObjectArray && data.isObjectArray == true) {
          this.$settings.isObjectArray = true;
          }
          else {
          this.$settings.isObjectArray = false;
          }
          if (data.isCaseSensitive && data.isCaseSensitive == true) {
          this.$settings.isCaseSensitive = true;
          }
          else {
          this.$settings.isCaseSensitive = false;
          }
          if (data.isDynamicData && data.isDynamicData == true) { // dynamic data
          this.$settings.isDynamicData = true;
          if (this._isNotBlank(data.url))
          this.$settings.url = data.url;
          if (this._isNotBlank(data.paramName))
          this.$settings.paramName = data.paramName;
          }
          else {
          this.$settings.isDynamicData = false;
          if (data.dataArray && data.dataArray.constructor == Array && data.dataArray.length > 0) {
          this.$settings.dataArray = data.dataArray;
          this._sortArray(); // sort the array or not
          }
          }
          if (this._isNotBlank(data.focusItemBgColor))
          this.$settings.focusItemBgColor = data.focusItemBgColor;
          if (this._isNotBlank(data.blurItemBgColor))
          this.$settings.blurItemBgColor = data.blurItemBgColor;
          if (this._isNotBlank(data.showText))
          this.$settings.showText = this._trim(data.showText);
          if (this._isNotBlank(data.showTextColor))
          this.$settings.showTextColor = data.showTextColor;
          if (this._isNotBlank(data.showTextFontStyle))
          this.$settings.showTextFontStyle = data.showTextFontStyle;
          if (this._isValidNum(data.maxShowRows))
          this.$settings.maxShowRows = data.maxShowRows;
          if (this._isValidNum(data.showTextOffsetLeft))
          this.$settings.showTextOffsetLeft = data.showTextOffsetLeft;
          if (this._isNotBlank(data.suggestBorderColorLT))
          this.$settings.suggestBorderColorLT = data.suggestBorderColorLT;
          if (this._isNotBlank(data.suggestBorderColorRB))
          this.$settings.suggestBorderColorRB = data.suggestBorderColorRB;
          if (this.$settings.input) {
          if (this._isNotBlank(data.itemFontSize))
          this.$settings.itemFontSize = data.itemFontSize;
          else if (this._isNotBlank(this._getInput().style.fontSize))
          this.$settings.itemFontSize = this._getInput().style.fontSize;
          }
          if (typeof(data.callback) == 'function'){
          this.$settings.callback = data.callback;;
          }
          else{
          if (this._isNotBlank(data.callback))
          this.$settings.callback = eval(data.callback);
          }
          this.$isIE = ((document.all) ? true : false) || navigator.userAgent.indexOf('MSIE') > 0;
          };

          /**
          * @desc: validate important params, whether can run script
          *
          * @return true or false
          */
          googleSuggest.prototype._isCanGo
          = function() {
          if (!this._getInput()) // invalid input
          return false;
          if (this.$settings.isDynamicData) { // dynamic data
          if (this._isBlank(this.$settings.url) || this._isBlank(this.$settings.paramName))
          return false;
          }
          else { // static data
          if (this.$settings.dataArray.length == 0) {
          return false;
          }
          else {
          // object array, formater eg:[{id: '1', name: 'java'}], only accept/process id and name property
          if (this.$settings.isObjectArray) {
          // here only validate the first element of array, so... I do not say whatever you know
          if (!this.$settings.dataArray[0].id || !this.$settings.dataArray[0].name)
          return false;
          }
          }
          }
          return true;
          };

          /**
          * @dese: sort the data array
          */
          googleSuggest.prototype._sortArray
          = function() {
          if (this.$settings.isSortData) {
          if (!this.$settings.isObjectArray) { // string array
          this.$settings.dataArray.sort(function(a, b) { // sort the array
          if (a.length > b.length)
          return 1;
          else if (a.length == b.length)
          return a.localeCompare(b);
          else
          return -1;
          });
          }
          else { // object array
          if (this.$settings.dataArray[0].id && this.$settings.dataArray[0].name) {
          this.$settings.dataArray.sort(function(a, b) { // sort the array
          if (a.name.length > b.name.length)
          return 1;
          else if (a.name.length == b.name.length)
          return a.name.localeCompare(b.name);
          else
          return -1;
          });
          }
          }
          }
          };

          /**
          * @desc: get current input
          *
          * @return current input object
          */
          googleSuggest.prototype._getInput
          = function() {
          return this.$settings.input;
          };

          /**
          * @desc: force blur the input
          */
          googleSuggest.prototype._forceBlurInput
          = function() {
          this._getInput().blur();
          };

          /**
          * @desc: initinalize the suggest
          */
          googleSuggest.prototype._initSuggest
          = function() {
          var input = this._getInput();
          var left = this._getAbsolutePosition(input)[0];
          var top = this._getAbsolutePosition(input)[1];
          var width = this._getWidthAndHeight(input)[0];
          var height = this._getWidthAndHeight(input)[1];
          this.$suggest = document.createElement('div');
          document.body.appendChild(
          this.$suggest);
          this.$suggest.style.position = 'absolute';
          this.$suggest.style.borderWidth = '1px';
          this.$suggest.style.borderStyle = 'solid';
          this.$suggest.style.borderLeftColor = this.$settings.suggestBorderColorLT;
          this.$suggest.style.borderTopColor = this.$settings.suggestBorderColorLT;
          this.$suggest.style.borderRightColor = this.$settings.suggestBorderColorRB;
          this.$suggest.style.borderBottomColor = this.$settings.suggestBorderColorRB;
          if (this.$isIE)
          this.$suggest.style.width = width + 'px';
          else
          this.$suggest.style.width = width - 2 + 'px';
          this.$suggest.style.left = left + 'px';
          this.$suggest.style.top = top + height - 1 + 'px';
          this.$suggest.style.display = 'none';
          };

          /**
          * @desc: init input and bind mouse and keyboard event
          */
          googleSuggest.prototype._initInput
          = function() {
          var input = this._getInput();
          input.suggest
          = this;
          input.value
          = this.$settings.showText;
          input.style.color
          = this.$settings.showTextColor;
          input.style.fontStyle
          = this.$settings.showTextFontStyle;
          input.onfocus
          = this._displaySuggest;
          input.onblur
          = this._inputBlur;
          input.onkeyup
          = this._catchKeyCode;
          };

          /**
          * @desc: current object may be input or suggest
          */
          googleSuggest.prototype._displaySuggest
          = function() {
          var o;
          if (this.$suggest) { // suggest
          o = this;
          }
          else {
          o
          = this.suggest; // input
          }
          if (!o.$settings.isDynamicData) // static data
          o._staticSuggest();
          else
          o._dynamicSuggest();
          };

          /**
          * @desc: create suggest with the static data array
          */
          googleSuggest.prototype._staticSuggest
          = function() {
          this.$focusItemIndex = -1;
          var inputVal = this._getInput().value;
          inputVal
          = this._trim(inputVal);
          if (this._isNotBlank(inputVal)) {
          if (inputVal != this.$settings.showText) {
          this._getInput().style.color = '#000000';
          this._getInput().style.fontStyle = 'normal';
          this.$suggest.innerHTML = '';
          this._createSuggestItems(inputVal);
          if (this.$suggest.children.length > 0)
          this._showSuggest();
          else
          this._hideSuggest();
          }
          else {
          this._getInput().style.color = this.$settings.showTextColor;
          this._getInput().style.fontStyle = this.$settings.showTextFontStyle;
          this._getInput().value = '';
          this._hideSuggest();
          }
          }
          else {
          this._hideSuggest();
          }
          }

          /**
          * @desc: create suggest, with the url to get dynamic data array
          */
          googleSuggest.prototype._dynamicSuggest
          = function() {
          this.$focusItemIndex = -1;
          var inputVal = this._getInput().value;
          inputVal
          = this._trim(inputVal);
          if (this._isNotBlank(inputVal) ) {
          if (inputVal != this.$settings.showText) {
          this._getInput().style.color = '#000000';
          this._getInput().style.fontStyle = 'normal';
          this.$suggest.innerHTML = '';
          var url = this._constructUrl() + inputVal;
          var xmlHttp = this._getAjax();
          xmlHttp.suggest
          = this;
          xmlHttp.onreadystatechange
          = function() {
          try{
          if (xmlHttp.readyState == this.suggest.$HTTP_STATE_COMPLETED) {
          if (xmlHttp.status == this.suggest.$HTTP_STATUS_OK) {
          var array = xmlHttp.responseText;
          if (this.suggest._isNotBlank(array)) {
          this.suggest.$settings.dataArray = eval(array);
          this.suggest._sortArray(); // sort or not
          var size = 0;
          if (this.suggest.$settings.dataArray > this.suggest.$settings.maxShowRows + 1)
          size
          = this.suggest.$settings.maxShowRows + 1;
          else
          size
          = this.suggest.$settings.dataArray.length;
          var o, item;
          if (this.suggest.$settings.isObjectArray) {
          for (var i = 0; i < size; i++) {
          o
          = this.suggest.$settings.dataArray[i];
          if (typeof(o) == 'object') {
          if (!o.id && !o.name) {
          alert(
          'Invalid format! The object must has id and name property, eg: [{id: 1, name: \'peter\'}, ...]');
          this.suggest._forceBlurInput();
          break;
          }
          else {
          item
          = this.suggest._createSuggestItem(o.name, inputVal);
          this.suggest.$suggest.appendChild(item);
          }
          }
          else {
          alert(
          'Invalid format! Correct format is like this [{id: 1, name: \'peter\'}, {id: \'admin\', name: \'administrator\'}]');
          this.suggest._forceBlurInput();
          break;
          }
          }
          }
          else { // string array
          for (var i = 0; i < size; i++) {
          o
          = this.suggest.$settings.dataArray[i];
          if (typeof(o) == 'string') {
          item
          = this.suggest._createSuggestItem(o, inputVal);
          this.suggest.$suggest.appendChild(item);
          }
          else {
          alert(
          'Invalid format! Correct format is like this [\'java\', \'javascript\', \'javaeye\']');
          this.suggest._forceBlurInput();
          break;
          }
          }
          }
          if (this.suggest.$suggest.children.length > 0)
          this.suggest._showSuggest();
          else
          this.suggest._hideSuggest();
          }
          else {
          this.suggest._hideSuggest();
          }
          }
          }
          }
          catch (e) {alert(e);}
          }
          xmlHttp.open(
          'GET', url, true);
          xmlHttp.send(
          null);
          }
          else {
          this._getInput().style.color = this.$settings.showTextColor;
          this._getInput().style.fontStyle = this.$settings.showTextFontStyle;
          this._getInput().value = '';
          this._hideSuggest();
          }
          }
          else {
          this._hideSuggest();
          }
          }

           

          google.suggest.js 第二部分

          /**
          * @desc: create the items show in the suggest, this method is used to static data, js fiter
          *
          * @param {Object} inputVal, input keywords
          */
          googleSuggest.prototype._createSuggestItems
          = function(inputVal) {
          var size = 0;
          if (this.$settings.dataArray > this.$settings.maxShowRows + 1)
          size
          = this.$settings.maxShowRows + 1;
          else
          size
          = this.$settings.dataArray.length;
          var reg = this._getRegExps(inputVal);
          var o, item;
          if (this.$settings.isObjectArray) {
          for (var i = 0; i < size; i++) {
          o
          = this.$settings.dataArray[i];
          if (typeof(o) == 'object') {
          if (!o.id && !o.name) {
          alert(
          'Invalid format! The object must has id and name property, eg: [{id: 1, name: \'peter\'}, ...]');
          this._forceBlurInput();
          break;
          }
          else {
          item
          = this._createSuggestItem(o.name, inputVal);
          this.$suggest.appendChild(item);
          }
          }
          else {
          alert(
          'Invalid format! Correct format is like this [{id: 1, name: \'peter\'}, {id: \'admin\', name: \'administrator\'}]');
          this._forceBlurInput();
          break;
          }
          }
          }
          else { // string array
          for (var i = 0; i < size; i++) {
          o
          = this.$settings.dataArray[i];
          if (typeof(o) == 'string') {
          if (o.match(reg)) {
          item
          = this._createSuggestItem(o, inputVal);
          this.$suggest.appendChild(item);
          }
          }
          else {
          alert(
          'Invalid format! Correct format is like this [\'java\', \'javascript\', \'javaeye\']');
          this._forceBlurInput();
          break;
          }
          }
          }
          };

          /**
          * @desc: create a item that show in suggest
          *
          * @param {Object} value, one value of the data array
          * @param {Object} inputVal, input keywords
          * @return item
          */
          googleSuggest.prototype._createSuggestItem
          = function(value, inputVal) {
          var v = value.replace(inputVal, '<span style="font-weight: normal;">' + inputVal + '</span>');
          var item = document.createElement('div');
          item.innerHTML
          = v;
          item.style.color
          = '#000000';
          item.style.backgroundColor
          = this.$settings.blurItemBgColor;
          item.style.fontWeight
          = 'bold';
          item.style.fontSize
          = this.$settings.itemFontSize;
          item.style.paddingLeft
          = this.$settings.showTextOffsetLeft + 'px';
          item.onmouseover
          = this._focusItem;
          item.onmouseout
          = this._blurItem;
          item.onmousedown
          = this._returnSelectedItem;
          item.suggest
          = this;
          return item;
          };

          /**
          * @desc: current object is suggest item(eg:<div>java</div>)
          */
          googleSuggest.prototype._focusItem
          = function() {
          this.style.backgroundColor = this.suggest.$settings.focusItemBgColor;
          };

          /**
          * @desc: return a Regular Expressions used to match keywords
          *
          * @param {Object} value, string
          * @return regexps
          */
          googleSuggest.prototype._getRegExps
          = function(value) {
          if (this.$settings.isCaseSensitive)
          return new RegExp(value, 'i');
          else
          return new RegExp(value);
          };

          /**
          * @desc: current object is suggest item(eg:<div>xxx</div>)
          */
          googleSuggest.prototype._blurItem
          = function() {
          this.style.backgroundColor = this.suggest.$settings.blurItemBgColor;
          };

          /**
          * @desc: current object is suggest item(eg:<div>javascript</div>)
          */
          googleSuggest.prototype._returnSelectedItem
          = function() {
          var name = this.innerHTML;
          var breg = new RegExp('<span style="font-weight: normal;">', 'i'); // <META content="IE=9" http-equiv="X-UA-Compatible">
          var mreg = new RegExp('<span style="font-weight: normal">', 'i'); // common, must remove ';'
          var ereg = new RegExp('</span>', 'i');
          name
          = name.replace(breg, '');
          name
          = name.replace(mreg, '');
          name
          = name.replace(ereg, '');
          this.suggest._getInput().value = name;
          var id = this.suggest._getIdbyName(name);
          if (this.suggest.$settings.callback) // callback function
          this.suggest.$settings.callback(id, name);
          this.suggest._forceBlurInput();
          this.suggest._hideSuggest();
          };

          /**
          * @desc: whether the suggest is hide
          *
          * @return true of false
          */
          googleSuggest.prototype._isSuggestHide
          = function() {
          return this.$suggest.style.display == 'none';
          };

          /**
          * @desc: current object may be input or suggest, show the suggest
          */
          googleSuggest.prototype._showSuggest
          = function() {
          if (this.$suggest) // suggest
          this.$suggest.style.display = 'block';
          else // input
          this.suggest.$suggest.style.display = 'block';
          };

          /**
          * @desc: current object may be input or suggest, hide the suggest
          */
          googleSuggest.prototype._hideSuggest
          = function() {
          var o;
          if (this.$suggest) { // suggest
          o = this;
          }
          else { // input
          o = this.suggest;
          }
          o.$suggest.style.display
          = 'none';
          };

          /**
          * @desc: current object is input, when the input is blur that should be do?
          */
          googleSuggest.prototype._inputBlur
          = function() {
          this.suggest._hideSuggest();
          var inputVal = this.value;
          if (this.suggest._isBlank(inputVal)) {
          this.value = this.suggest.$settings.showText;
          this.style.color = this.suggest.$settings.showTextColor;
          this.style.fontStyle = this.suggest.$settings.showTextFontStyle;
          }
          };

          /**
          * @desc: current object is input, catch the keyboard event, judge to show or hide suggest
          */
          googleSuggest.prototype._catchKeyCode
          = function() {
          var keyCode = 0;
          if (this.suggest.$isIE) {
          var keyCode = event.keyCode;
          if (keyCode == this.suggest.$DOWN || keyCode == this.suggest.$UP) { // down or up
          var isUp = true;
          if (keyCode == this.suggest.$DOWN) // down
          isUp = false;
          this.suggest._changeFocusItem(isUp);
          }
          else if (keyCode == this.suggest.$ENTER) {
          this.suggest._catchEnter();
          }
          else {
          this.suggest._displaySuggest();
          }
          }
          else {
          this.suggest._displaySuggest();
          }
          };

          /**
          * @desc: used to catch enter event
          */
          googleSuggest.prototype._catchEnter
          = function() {
          var name = this._getInput().value;
          var id = this._getIdbyName(name);
          if (this.$settings.callback) // callback function
          this.$settings.callback(id, name);
          this._forceBlurInput();
          this._hideSuggest();
          }

          /**
          * @desc: change the focus item and change the input text's style that show in the suggest
          *
          * @param {Object} isUp, keyboard event, up or down
          */
          googleSuggest.prototype._changeFocusItem
          = function(isUp) {
          if (this._isSuggestHide()) {
          this._showSuggest();
          }
          else {
          if (isUp)
          this.$focusItemIndex--;
          else
          this.$focusItemIndex++;
          }
          var maxIndex = this.$suggest.children.length - 1;
          if (this.$focusItemIndex < 0) {
          this.$focusItemIndex = maxIndex;
          }
          if (this.$focusItemIndex > maxIndex) {
          this.$focusItemIndex = 0;
          }
          var breg = new RegExp('<span style="font-weight: normal;">', 'i'); // <META content="IE=9" http-equiv="X-UA-Compatible">
          var mreg = new RegExp('<span style="font-weight: normal">', 'i'); // common, must remove ';'
          var ereg = new RegExp('</span>', 'i');
          var text;
          for (var i = 0; i <= maxIndex; i++) {
          if (i == this.$focusItemIndex) {
          text
          = this.$suggest.children[i].innerHTML;
          text
          = text.replace(breg, '');
          text
          = text.replace(mreg, '');
          text
          = text.replace(ereg, '');
          this._getInput().value = text;
          this.$suggest.children[i].style.backgroundColor = this.$settings.focusItemBgColor;
          }
          else {
          this.$suggest.children[i].style.backgroundColor = this.$settings.blurItemBgColor;
          }
          }
          };

          /**
          * @desc: get a html element's absolute position
          *
          * @param {Object} o, html element
          * @return array, value 1 is x coordinate and value 2 is y coordinate
          */
          googleSuggest.prototype._getAbsolutePosition
          = function(o) {
          var array = new Array();
          var top = 0, left = 0;
          do {
          top
          += o.offsetTop;
          left
          += o.offsetLeft;
          }
          while (o = o.offsetParent);
          array[
          0] = left;
          array[
          1] = top;
          return array;
          };

          /**
          * @desc: get a html element's width and height
          *
          * @param {Object} o, html element
          * @return array that first value is width and second value is height
          */
          googleSuggest.prototype._getWidthAndHeight
          = function(o) {
          var array = new Array();
          array[
          0] = o.offsetWidth;
          array[
          1] = o.offsetHeight;
          return array;
          };

          /**
          * @desc: trim a string
          *
          * @param {Object} string
          * @return string that remove the left space and right space, space(space and tab)
          */
          googleSuggest.prototype._trim
          = function(string) {
          return string.replace(/(^\s*)|(\s*$)/g, '');
          };

          /**
          * @desc: validate a string is null or ''
          *
          * @param {Object} string
          * @return true if is not '' or undefined, else false
          */
          googleSuggest.prototype._isValidString
          = function(string) {
          if (string && this._trim(string))
          return true;
          return false;
          }

          /**
          * @desc: validate number
          *
          * @param {Object} num
          * @return true if is valid number, else false
          */
          googleSuggest.prototype._isValidNum
          = function(num) {
          if (!isNaN(parseInt(num)))
          return true;
          return false;
          }

          /**
          * @desc: get an ajax object
          *
          * @return ajax object, this.$xmlHttp or new XMLHttpRequest
          */
          googleSuggest.prototype._getAjax
          = function() {
          if (!this.$xmlHttp) {
          this.$xmlHttp = this._getXMLHttpRequest();
          }
          if (this.$xmlHttp.readyState != this.$HTTP_STATE_COMPLETED) {
          return this._getXMLHttpRequest();
          }
          return this.$xmlHttp;
          };

          /**
          * @desc: create a XMLHttpRequest object
          *
          * @return a new XMLHttpRequest object
          */
          googleSuggest.prototype._getXMLHttpRequest
          = function() {
          var xmlHttp;
          if (window.XMLHttpRequest) {
          xmlHttp
          = new XMLHttpRequest();
          }
          else if (window.ActiveXobject) {
          try {
          xmlHttp
          = new ActiveXobject('MSXML2XMLHTTP');
          }
          catch (e){
          try {
          xmlHttp
          = new ActiveXobject('Microsoft.XMLHttp');
          }
          catch (e){}
          }
          }
          return xmlHttp;
          }

          /**
          * @desc: construct the full url with the user specified url and param name
          *
          * @return full url
          */
          googleSuggest.prototype._constructUrl
          = function() {
          var url = this.$settings.url;
          var paramName = this.$settings.paramName;
          if (url.indexOf('?') == -1)
          url
          += '?' + paramName + '=';
          else
          url
          += '&' + paramName + '=';
          return url;
          };

          /**
          * @desc: so... name must be unique, else will be wrong, see below you will be understand
          *
          * @param {Object} name, object array name
          * @return object array id value
          */
          googleSuggest.prototype._getIdbyName
          = function(name) {
          var id = null;
          var array = this.$settings.dataArray;
          for (var i = 0; i < array.length; ++i) {
          if (array[i].name == name)
          return array[i].id;
          }
          return id;
          }

          /**
          * blank means null/undefined/''/tab
          *
          * @param {Object} string
          * @return true or false
          */
          googleSuggest.prototype._isBlank
          = function(string) {
          if (string == undefined) // null or un init
          return true;
          if (this._trim(string) == '')
          return true;
          return false;
          }

          /**
          * not blank
          *
          * @param {Object} string
          * @return true or false
          */
          googleSuggest.prototype._isNotBlank
          = function(string) {
          return !this._isBlank(string);
          }

           

          GetDataServlet.java

          package bing;

          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.List;

          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;

          /**
          * Ajax獲取模擬數(shù)據(jù)處理類
          *
          *
          @author Bing
          * @date 2011-4-22
          *
          */
          public class GetDataServlet extends HttpServlet {

          private static final long serialVersionUID = -5467391979358615867L;
          private String[] datas = { "JAVA", "JAVA游戲", "JAVA下載", "javascript",
          "javaeye", "JAVA教程", "java游戲下載", "javascript教程", "JAVA虛擬機",
          "JAVA正則表達式", "77元廉租房", "77元特惠房", "77元大床房", "77元特惠大床房", "77元 7天",
          "77元特惠房預訂專區(qū)", "7天77元", "7天連鎖酒店77元", "程序員", "程序員之家", "程序員考試",
          "程序員面試寶典", "程序員工資", "程序員的老婆是誰", "程序員論壇", "程序員修煉之道", "程序員雜志",
          "程序員招聘" };
          private List<Bean> beans = new ArrayList<Bean>();

          public GetDataServlet() {
          super();
          initializeBeans();
          }

          public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
          response.setContentType(
          "text/html;charset=GBK");
          response.setCharacterEncoding(
          "GBK");
          String dataType
          = request.getParameter("dataType");
          String keywords
          = request.getParameter("keywords");
          String dataString
          = "";
          if ("object".equals(dataType)) {
          dataString
          = getObjectArray(keywords);
          }
          else {
          dataString
          = getStringArray(keywords);
          }
          response.getWriter().print(dataString);
          }

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

          /**
          * 字符串數(shù)組
          *
          * format: ['java', 'javascript', 'javaeye']
          *
          *
          @param keywords
          *
          @return
          */
          private String getStringArray(String keywords) {
          System.out.println(
          "keywords: [" + keywords + "]");
          String stringArray
          = "";
          if (keywords != null && !"".equals(keywords)) {
          keywords
          = keywords.toLowerCase();
          StringBuffer buffer
          = new StringBuffer();
          for (String data : datas) {
          data
          = data.toLowerCase();
          if (data.indexOf(keywords) != -1)
          buffer.append(
          "'").append(data).append("'").append(", ");
          }
          stringArray
          = buffer.toString();
          if (!"".equals(stringArray)) {
          stringArray
          = stringArray.substring(0, stringArray.lastIndexOf(", "));
          stringArray
          = "[" + stringArray + "]";
          }
          System.out.println(
          "返回數(shù)據(jù)為字符串數(shù)組,內(nèi)容:" + stringArray);
          }
          return stringArray;
          }

          /**
          * 對象數(shù)組(如果使用JSON就方便多了)
          *
          * format: [{id: '1', name: 'java'}, {id: '2', name: 'javascript'}]
          *
          *
          @param keywords
          *
          @return
          */
          private String getObjectArray(String keywords) {
          keywords
          = keywords.toLowerCase();
          StringBuffer buffer
          = new StringBuffer();
          for (Bean bean : beans) {
          String id
          = bean.getId();
          String name
          = bean.getName();
          String temp
          = bean.getName().toLowerCase();
          if (temp.indexOf(keywords) != -1)
          buffer.append(
          "{").append("id: '").append(id).append("', name: '").append(name).append("'}, ");
          }
          String objectArray
          = buffer.toString();
          if (!"".equals(objectArray)) {
          objectArray
          = objectArray.substring(0, objectArray.lastIndexOf(", "));
          objectArray
          = "[" + objectArray + "]";
          }
          System.out.println(
          "返回數(shù)據(jù)為對象數(shù)組,內(nèi)容:" + objectArray);
          return objectArray;
          }

          private void initializeBeans () {
          for (int i = 0; i < datas.length; i++) {
          beans.add(
          new Bean(String.valueOf(i), datas[i]));
          }
          }

          }

           

          Bean.java

          package bing;

          public class Bean {

          private String id;
          private String name;

          public Bean() {
          super();
          }

          public Bean(String id, String name) {
          super();
          this.id = id;
          this.name = name;
          }

          public String getId() {
          return id;
          }

          public void setId(String id) {
          this.id = id;
          }

          public String getName() {
          return name;
          }

          public void setName(String name) {
          this.name = name;
          }

          }

           

          web.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation
          ="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
          >
          <servlet>
          <description>get Google suggest data</description>
          <display-name>GetData</display-name>
          <servlet-name>GetDataServlet</servlet-name>
          <servlet-class>bing.GetDataServlet</servlet-class>
          </servlet>

          <servlet-mapping>
          <servlet-name>GetDataServlet</servlet-name>
          <url-pattern>/servlet/getData</url-pattern>
          </servlet-mapping>
          <welcome-file-list>
          <welcome-file>Google.html</welcome-file>
          </welcome-file-list>
          </web-app>

           

          不滿意的地方是沒有弄好火狐的鍵盤事件,即上下鍵或者回車鍵,都不知道怎么捕捉,網(wǎng)上搜索了下,不過都不怎么好使,就放棄了。

          當前默認是使用靜態(tài)數(shù)據(jù),如果部署到Tomcat中后,可將Google.html中的 isDynamicData: false  改為true即可,之后可以觀察Tomcat的控制臺輸出。

          歡迎網(wǎng)友們多多交流!

          主站蜘蛛池模板: 乐昌市| 永康市| 元阳县| 洪洞县| 太保市| 通榆县| 全州县| 淳安县| 当阳市| 威信县| 永定县| 襄垣县| 文安县| 康乐县| 临朐县| 龙胜| 黑水县| 卢湾区| 绥江县| 涞水县| 哈尔滨市| 蕉岭县| 灌阳县| 内江市| 岚皋县| 民勤县| 鹰潭市| 白玉县| 会昌县| 丰镇市| 岚皋县| 华池县| 县级市| 岳阳市| 濮阳市| 顺义区| 仁布县| 淮北市| 博湖县| 图们市| 台湾省|