ホームページ >ウェブフロントエンド >jsチュートリアル >jquery intellSeach.js_jquery に基づくインテリジェント プロンプト コントロールの実装

jquery intellSeach.js_jquery に基づくインテリジェント プロンプト コントロールの実装

WBOY
WBOYオリジナル
2016-05-16 15:10:311320ブラウズ

1. 需要

ユーザー エクスペリエンスを向上させるために、Baidu のようなリアルタイムのインテリジェントなプロンプトを実現したいと考えています。たとえば、企業の人事管理システムで、Li XX を検索したい場合は、「Li」と入力するだけで、システムは自然に Li という名前の従業員を表示するため、ユーザーにとって便利です。率直に言うと、ユーザーが入力している間にシステムは関連する結果を表示します。あるいは、ユーザーが検索ボックスをクリックすると、たとえば 360 や Baidu では、今日の主要なニュースや大規模な検索コンテンツが表示されます。音量。

jquery にはすでにオートコンプリートと呼ばれるこのようなプラグインがありますが、使いやすいとは思いません。オートコンプリートの紹介もたくさんありますので、興味のある方は試してみてください。

タイトルからわかるように、これは単なるプラグインであり、バックグラウンド検索の関連アルゴリズムやプロセスについては説明しません。つまり、バックグラウンドは特定の形式でデータを返し、コントロールはその役割を果たします。結果をレンダリングします。さて、最初にレンダリングを見てみましょう:

スタイルはコントロールとは何の関係もありません。入力テキストのみが必要です。

2. パラメータの説明

コントロールは送信形式としてjson形式を使用します。多くのパラメータがあり、そのほとんどにはデフォルト値があります (詳細についてはソースコードを参照してください)。一部のパラメータは一般的に使用されない可能性があるため、デフォルト値をそのままにしておきます。以下のように:

url: リクエストアドレス。例: Handler.ashx、バックグラウンドでデータを取得するためのアドレス

property: 表示される json オブジェクトのプロパティ。 ["tom","tom cat","tom2"] の形式を直接返す場合、この属性を設定する必要はありませんが、場合によっては [{"Name":"tom","ID":) を返すことがあります。 " 001"},{"名前":"tom cat","ID":"002"},{"名前":"tom2","ID":"003"}] このフォームでは名前が表示されます。次に、このプロパティを「名前」に設定します。クリック時に取得したいクリックされた項目のIDは、クリックイベントを利用できます。

itemNumber: 表示されるアイテムの数。

isEmptyRequest: 空白の場合にリクエストを開始するかどうか。前述したように、検索ボックスをクリックしたときにコンテンツを推奨したい場合 (現時点ではコンテンツがありません)、この属性を true に設定すると、リクエストが開始されます。

defaultValue: デフォルト値。通常、「キーワードを入力してください...」のようなプロンプトが表示されます。

width: ドロップダウン リストの幅。

aligner: 位置合わせされる要素。

maxHeight: 最大高さ。この高さを設定すると、それを超えるとスクロール バーが表示されます。                                                                          

ajax:{ タイムアウト: タイムアウト
キャッシュ: キャッシュするかどうか
}、

イベント:{ setData: リクエストを送信する前にトリガーされます。パラメータを設定するために使用されます
itemClick: item
をクリックするとトリガーされます enterKeydown: Enter キーを押すとトリガーされます
beforeRender: すべてのアイテムがレンダリングされる前にトリガーされます
endRender: すべてのアイテムがレンダリングされた後にトリガーされます
itemBeforeRender: アイテムがレンダリングされる前にトリガーされます
itemAfterRender: アイテムがレンダリングされた後にトリガーされます
beforeSend: リクエストを送信する前にトリガーされます。ユーザーはリクエストヘッダパラメータなどを設定します。これは、jquery ajax の beforeSend に相当します。
}

イベント内のメソッドは適切なタイミングでトリガーされます。すべてのメソッドは 4 つの属性を持つオブジェクトであるパラメーターを受け取りますが、そのような属性がない場合は空になることに注意してください。次の属性が含まれます:

   jthis: input 的 jQuery 物件。

   jItem: 項目的 jQuery 物件。

     data: 傳回的 json 字串。如果在前台需要對返回 json 再進行處理,那麼可以透過 data 屬性取得,處理完成後,需要將 json 字串 return。

   event: 事件對象,如按下 enter 時的事件對象。

三、例

  使用範例:

$("#search").intellSearch({
  url:"Handler.ashx",
  property:"Name",
  itemNumber:5,
  isEmptyRequest:false,
  defaultValue:"请输入关键字...",    
  width:$("#search").width() + 2,
  maxHeight:-1,
  event:{
    itemClick:function(obj){
      alert(obj.item.ID);
    },
    enterKeydown:function(obj){
      if(obj.item){
        alert("有当前项");
      }else{
        alert("没有当前项");
      }
    }
  }  
});

四、總結  

  如果你還有自己的邏輯需要處理,也支援鍊式調用,大可以這樣寫$("#search").intellSearch({參數...}).focus(function(){你的處理...});

  分享該外掛希望能幫助到有需要的朋友,主要用於學習。由於是v1.0,可能還有一些bug,有發現的朋友也可以告訴我,我會及時修正。  

附原始碼

js程式碼

/*搜索智能提示 v1.0
 date:2015.09.08 
*/
;(function(w,$){
  $.fn.intellSearch = function(options){
    var jthis = this;
    var _dftOpts = {
      url:"",//请求地址或数组          
      property:"",//要显示的json对象的属性
      itemNumber:5,//显示的条数
      isEmptyRequest:false,//focus空白是否发起请求
      defaultValue:"",//默认值
      width:0,//列表宽度
      aligner:jthis,//要对齐的元素
      maxHeight:-1,//最大高度          
      ajax:{
        timeout:3000,//超时时间
        cache:true//是否缓存
      },
      event:{
        /*参数说明:parameter:{jthis:"jq input",jItem:"jq item",data:"json result",event:"event"}*/
        setData:null,//设置参数
        itemClick:null,//点击项触发
        enterKeydown:null,//按下enter键触发
        beforeRender:null,//所有项呈现前触发
        endRender:null,//所有项呈现后触发
        itemBeforeRender:null,//项呈现前触发
        itemAfterRender:null,//项呈现后触发
        beforeSend:null//发送请求前触发
      }
    };
    $.extend(_dftOpts,options);
    if(!_dftOpts.url){
      throw Error("url不能为空!");
    }
    var jResult;        
    var _value = "";    
    var _ajax = _dftOpts.ajax;
    var _event = _dftOpts.event;
    var _cache = [];
    var _focusCount = 0;//防止focus触发多次(sogou)
     
    /*on window*/
    window.intellObj = window.intellObj || {}; /*for global event*/
    window.intellDocumentClick = window.intellDocumentClick || function(e){
      if(!window.intellObj.jthis){
        return;
      }
      if(e.target !== window.intellObj.jthis[0]){
        setIntellObj(null);
      }
    }
    window.intellDocumentKeydown = window.intellDocumentKeydown || function(e){
      var jthis = window.intellObj.jthis;
      if(!jthis){
        return;
      }
      var code = e.keyCode;
      var value = window.intellObj.value;      
      var jResult,jCurItem,keyword;
      if(code === 13 || code === 38 || code === 40){
        jResult = window.intellObj.jResult;
        jItems = jResult.find("li");
        jCurItem = jResult.find("li.cur");
        if(code === 13){
          if(jCurItem.length > 0){
            jCurItem.click();
          }else{
            setIntellObj(null);           
            if(_event.enterKeydown){
              _event.enterKeydown({"jthis":jthis,"event":e});
            }
          }
          jthis.blur();
        }else if(jItems.length > 0){
          if(code === 38){
            if(jCurItem.length <= 0){
              jCurItem = jItems.last();
              jCurItem.addClass("cur");
              keyword = jCurItem.text();
            }else{
              var index = jCurItem.index();
              jCurItem.removeClass("cur");
              if(index <= 0){
                keyword = value;              
              }else{
                jCurItem = jItems.eq(index-1);
                jCurItem.addClass("cur");
                keyword = jCurItem.text();
              }
            }
            jthis.val(keyword);
          }else{
            if(jCurItem.length <= 0){
              jCurItem = jItems.first();
              jCurItem.addClass("cur");
              keyword = jCurItem.text();
            }else{
              var index = jCurItem.index();
              jCurItem.removeClass("cur");
              if(index + 1 >= jItems.length){
                keyword = value;
              }else{
                jCurItem = jItems.eq(index+1);
                jCurItem.addClass("cur");
                keyword = jCurItem.text();
              }
            }
            jthis.val(keyword);
          }
        }
      }
    }
    /*event handler*/
    $.fn.unintell = function(){
      remove();
    }
    $(document).unbind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown})
          .bind({click:window.intellDocumentClick,keydown:window.intellDocumentKeydown});
    jthis.focus(function(){
      _focusCount++;
      if(_focusCount > 1){
        return;
      }
      if(window.intellObj.jthis && jthis !== window.intellObj.jthis){
        setIntellObj(null);
      }
      var keyword = attrValue();
      if(keyword === _dftOpts.defaultValue){
        keyword = "";
        attrValue(keyword);
      }
      if(keyword || _dftOpts.isEmptyRequest){
        sendRequest();
      }
    })
    jthis.blur(function(){      
      _focusCount = 0;
      if(!attrValue()){
        attrValue(_dftOpts.defaultValue);
      }      
    })
    jthis.keyup(function(e){
      if(e.keyCode === 38 || e.keyCode === 40){
        return;
      }
      var keyword = attrValue();
      if(!keyword){
        remove();
        window.intellObj.value = _value = "";
        return;
      }
      if(keyword !== _value){
        window.intellObj.value = _value = keyword;
        sendRequest();
      }
    });
     
    return initBox();
     
    /*function*/
    function initBox(){
      attrValue(_dftOpts.defaultValue);
      return jthis;
    }    
    function initIntell(){      
      generate();
      register();
      setIntellObj({jthis:jthis,jResult:jResult});
    }
    function generate(){
      var offset = _dftOpts.aligner.offset();
      var width = _dftOpts.width &#63; _dftOpts.width : _dftOpts.aligner.width();
      jResult = $("<ul>",{"class":"intellResult"});
      jResult.width(width).css({"position":"absolute","left":offset.left,"top":offset.top + jthis.outerHeight()});
      $("body").append(jResult);
      if(_dftOpts.maxHeight > 0){
        jResult.height(_dftOpts.maxHeight).css("overflowY","scroll");
      }
    }
    function remove(){
      if(jResult){
        jResult.remove();
        jResult = null;
      }
    }
    function register(){
      jResult.on("click","li",function(){
        var jItem = $(this);
        var index = jItem.index();
        var keyword = jItem.text();
        attrValue(keyword);        
        _value = keyword;        
        if(_event.itemClick){
          _event.itemClick({"jthis":jthis,"jItem":jItem,"item":_cache[index]});
        }
      }).on("mouseenter","li",function(){
        $(this).siblings("li").removeClass("cur").end().addClass("cur");
      }).on("mouseleave","li",function(){
        $(this).removeClass("cur");
      });
    }
    function setIntellObj(obj){
      if(!obj){
        if(window.intellObj.jResult){
          window.intellObj.jResult.remove();
        }
        window.intellObj.jthis = null;
        window.intellObj.jResult = null;
      }else{
        window.intellObj.jthis = obj.jthis;
        window.intellObj.jResult = obj.jResult;
      }
    }
    function sendRequest(){
      var data;
      if(_event.setData){        
        data = _event.setData({"jthis":jthis});
      }
      $.ajax({
        url:_dftOpts.url,
        data:data,
        cache:_ajax.cache,
        timeout:_ajax.timeout,
        beforeSend:function(xhr){
          if(_event.beforeSend){
            _event.beforeSend(xhr);
          }
        },
        success:function(data){
          remove();
          showData(data);
        },
        error:null
      });
    }
    function showData(data){
      data = $.trim(data) &#63; $.parseJSON(data) : data;
      if(_event.beforeRender){
        var rs = _event.beforeRender({"jthis":jthis,"data":data});
        if(rs === false){
          return;
        }
        if(rs !== undefined){
          data = rs;
        }
      }
      if(!data){
        return;
      }
      var jItem,jA,jSpan,hasProp,item,text,otherTexts,isRender,index;
      var list = $.isArray(data) &#63; data : [data];
      var length = list.length;
      length = length > _dftOpts.itemNumber &#63; _dftOpts.itemNumber : list.length;
      if(length <= 0){
        return;
      }
      initIntell();
      _cache.length = 0;
      hasProp = list[0][_dftOpts.property];
      for(var i=0;i<length;i++){
        item = list[i];
        if(item === null || item === undefined){
          continue;
        }
        text = hasProp &#63; item[_dftOpts.property] : item;
        text = $.trim(text.toString());
        if(text === ""){
          continue;
        }
        jItem = $("<li>",{"class":"intellResult_item"});
        jA = $("<a>",{"title":text}).appendTo(jItem);
        jSpan = $("<span>").appendTo(jA);
        index = text.toLowerCase().indexOf(_value.toLowerCase());
        otherTexts = splitText(text,_value,index);
        if(otherTexts){
          jSpan.text(text.substr(index,_value.length));
          if(otherTexts.length > 1){
            $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);
            $("<b>",{"text":otherTexts[1]}).insertAfter(jSpan);
          }else{
            if(index === 0){
              $("<b>",{"text":otherTexts[0]}).insertAfter(jSpan);
            }else{
              $("<b>",{"text":otherTexts[0]}).insertBefore(jSpan);
            }
          }
        }else{
          jSpan.text(text);
        }
        isRender = true;
        if(_event.itemBeforeRender){
          isRender = _event.itemBeforeRender({"jthis":jthis,"jItem":jItem,"item":item});
        }
        if(isRender !== false){
          jResult.append(jItem);
          if(_event.itemAfterRender){
            _event.itemAfterRender({"jthis":jthis,"jItem":jItem,"item":item});
          }
        }
        _cache.push(item);
      }
      if(_event.endRender){
        _event.endRender({"jthis":jthis});
      }
      jResult.show();
    }
    function attrValue(value){
      if(!value && value != ""){
        return $.trim(jthis.val());
      }
      jthis.val(value);
    }
    function splitText(text,value,index){
      var tlength = text.length;
      var vlength = value.length;
      if(index === -1){
        return null;
      }
      if(index === 0){
        if(index + vlength >= tlength){
          return null;
        }
        return [text.substr(index + vlength)];
      }
      if(index + vlength >= tlength){
        return [text.substr(0,index)];
      }
      return [text.substr(0,index),text.substr(index + vlength)];
    }
  }
})(window,jQuery);

樣式

.intellResult{margin:0;padding:0;background:#fff;border:1px solid #b6b6b6;clear:both;z-index:999;display:none;}
.intellResult li{margin:0;padding:0;padding:5px 15px;height:20px;line-height:20px;overflow:hidden;text-overflow:ellipsis;cursor:pointer;white-space:nowrap;}
.intellResult li.cur{background:#E5E0E0;}

以上就是本文的全部內容,希望對大家的學習有所幫助。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。