Maison > Article > interface Web > Implémentation d'un contrôle d'invite intelligent basé sur jquery intellSeach.js_jquery
1. Demande
Nous rencontrons souvent le besoin de [recherche sur site]. Afin d'améliorer l'expérience utilisateur, nous espérons obtenir des invites intelligentes en temps réel comme celles de Baidu. Par exemple : dans le système de gestion du personnel d'une entreprise, si vous souhaitez rechercher Li XX, entrez simplement « Li », et le système invitera naturellement certains employés nommés Li, ce qui est pratique pour les utilisateurs. Pour parler franchement, le système demandera des résultats pertinents pendant que l'utilisateur tape ; ou, lorsque l'utilisateur clique sur le champ de recherche, il recommandera certains contenus. Par exemple, 360 et Baidu proposeront les principales actualités ou contenus du jour avec une recherche approfondie. volume.
jquery possède déjà un plug-in comme celui-ci, appelé autocomplete, mais je ne pense pas qu'il soit facile à utiliser. Il existe également de nombreuses introductions à la saisie semi-automatique. Les amis intéressés peuvent l'essayer.
Comme vous pouvez le constater d'après le titre, il ne s'agit que d'un plug-in et ne discutera pas des algorithmes et des processus pertinents de recherche en arrière-plan. En d'autres termes, l'arrière-plan renvoie les données dans un format spécifique et le contrôle en est responsable. rendre les résultats. ok, regardons d'abord les rendus :
Le style n'a rien à voir avec le contrôle, seul un texte de saisie est nécessaire.
2. Description des paramètres
Le contrôle utilise le format json comme format de transmission. Il existe de nombreux paramètres, dont la plupart ont des valeurs par défaut (voir le code source pour plus de détails). Certains peuvent ne pas être couramment utilisés, alors conservez simplement les valeurs par défaut. Comme suit :
url : Adresse de la demande. Par exemple : Handler.ashx, l'adresse d'obtention des données en arrière-plan
property : La propriété de l'objet json à afficher. Si nous renvoyons directement le formulaire ["tom", "tom cat", "tom2"], alors cet attribut n'a pas besoin d'être défini mais parfois nous renverrons [{"Name": "tom", "ID": " 001"},{"Name": "tom cat", "ID": "002"}, {"Name": "tom2", "ID": "003"}] Dans ce formulaire, le nom est affiché. Définissez ensuite cette propriété sur "Nom". Quant à l'ID de l'élément cliqué que nous souhaitons obtenir en cliquant, nous pouvons utiliser l'événement click.
itemNumber : Le nombre d'éléments affichés.
isEmptyRequest : S'il faut lancer une demande lorsqu'elle est vide. Comme mentionné précédemment, si vous souhaitez recommander du contenu lorsque vous cliquez sur le champ de recherche (il n'y a pas de contenu pour le moment), définissez cet attribut sur true et une demande sera lancée.
defaultValue : Valeur par défaut. Habituellement, il s'agira d'une invite du type : "Veuillez saisir le mot-clé...".
width : Largeur de la liste déroulante.
aligner : L'élément à aligner.
maxHeight : Hauteur maximale. Si cette hauteur est définie, des barres de défilement apparaîtront lorsqu'elle est dépassée.
ajax :{
Délai d'attente : Délai d'expiration
cache : s'il faut mettre en cache
},
événement :{
setData : Déclenché avant l'envoi de la requête. Utilisé pour définir les paramètres
itemClick : déclenché en cliquant sur l'élément
enterKeydown : déclenché en appuyant sur la touche Entrée
beforeRender : déclenché avant que tous les éléments ne soient rendus
endRender : déclenché une fois que tous les éléments sont rendus
itemBeforeRender : déclenché avant le rendu de l'élément
itemAfterRender : déclenché après le rendu de l'élément
beforeSend : déclenché avant l'envoi de la demande. L'utilisateur définit les paramètres d'en-tête de requête, etc., ce qui est équivalent à beforeSend de jquery ajax.
>
jthis : objet jQuery d'entrée.
jItem : L'objet jQuery de l'élément .
data : La chaîne json renvoyée. Si le json renvoyé doit être traité au premier plan, il peut être obtenu via l'attribut data. Une fois le traitement terminé, la chaîne json doit être renvoyée.
event : Objet événement, tel que l'objet événement lorsque vous appuyez sur Entrée.
3. Exemple
Exemple d'utilisation :
$("#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("没有当前项"); } } } });
4.Résumé
Si vous avez toujours votre propre logique à traiter et que les appels en chaîne sont pris en charge, vous pouvez écrire $("#search").intellSearch({parameters...}).focus(function(){yourprocessing... });
Le partage de ce plug-in espère aider des amis dans le besoin. Il est principalement utilisé pour l'apprentissage. Puisqu'il s'agit de la version 1.0, il peut encore y avoir des bugs. Les amis qui les trouvent peuvent également me le signaler et je les corrigerai à temps.
Code source ci-joint
code 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 ? _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) ? $.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) ? data : [data]; var length = list.length; length = length > _dftOpts.itemNumber ? _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 ? 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);
Style
.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;}
Ce qui précède représente l’intégralité du contenu de cet article, j’espère qu’il sera utile à l’étude de chacun.