搜索框组件1
当数据量很大时,keyup时不断地向服务器请求新的的数据,不断渲染搜搜结果。
代码实现:
function onKeyUpcbfn_table(input){ var _input = input.value; if (searchCount === 0) { searchCount = 1; WT.Tool.ajax({apiName:'/symbol/get_symbol_name',param:{search:_input},cbFn:{ onSuccess:function(d){ searchCount = 0; var symbol=d.data; if (symbol.length<=0) { return; } symbol = symbol.map(function(items,i){ return {idx:items.id,txt:items.name,val:items.name} }) search.render(symbol); search.input.focus(); }, onError:function(){ searchCount = 0; } }}); } }
搜索框2
当数据量不是很多时可以只请求1次,然后处理拿到的数据。
实现步骤先获取数据-》加载默认数据-》实现搜索功能-》实现选中结果字体变蓝-》添加选中事件-》添加键盘按up,down键向上向下选中元素-》点击任意位置让new出的DOM元素消失。
代码实现
function symbolGet_table(cbFn1){//商品及其属性加在 WT.Tool.ajax({apiName:'/symbol/get_symbol_name',param:{},cbFn:{ onSuccess:function(d){ var symbol=d.data;//pid:名称对应 商品33,现货市场34,外汇市场35,股指期货36 if (!WT.G.P.symbolList[0]) { WT.G.P.symbolList = [[],[],[],[],[]]; symbol.map(function(item){ WT.G.P.symbolList[0].push(item); switch(parseInt(item.pid)){ case 33: WT.G.P.symbolList[1].push(item); break; case 34: WT.G.P.symbolList[2].push(item); break; case 35: WT.G.P.symbolList[3].push(item); break; case 36: WT.G.P.symbolList[4].push(item); break; default: console.log('去问小冯冯Pid有没有改变'); break; } return; }); } // console.log(WT.G.P.symbolList); cbFn1(symbol); } }}); }
function searchSymbolFn(x,y,cbFn){//商品名搜索 if (WT.G.P.symbolList[0].length > 0) { selectedList = null; searchSel = []; var oSearch = $DB.adElm('','div').cn('pa ml10 mt10 List_bs_sign').css('z-index:51').h(laytpl(search_content_tlp.help()).render({})); oSearch.evt('mousedown',function(){ var e=WT.e.fix(e); e.stop(); }); oSearch.evt('mouseenter',function(){ oSearchInput.focus(); }); oSearch.css(WT.box([x,y,260,300].join(','))); var oSearchList = $(oSearch.querySelector('[opt=symbol_list]')); var oSearchInput = $(oSearch.querySelector('[opt=search_input]')); oSearchInput.focus(); var oSearchUl = $(oSearch.querySelector('[opt=search_ul]')); searchRenderFn(WT.G.P.symbolList[0],oSearchList,true);//加载查询结果 var selected = $(oSearchUl.querySelector('li:first-child')); oSearchUl.evt('mousedown',function(){//点击分类按钮 var e = WT.e.fix(e),_e = e.t; var sInput = oSearchInput.val().toLow().trim(); while(_e.tagName !== 'UL'){ if(_e.tagName === 'LI'){ _e.cn('bc_51 c_0 tac r2 pt3l8 mt-5'); switch(+_e.attr('opt')){ case 0: searchRenderFn(WT.G.P.symbolList[0],oSearchList,true); searchRenderValFn(searchSel,oSearchList,sInput); break; case 1: searchRenderFn(WT.G.P.symbolList[1],oSearchList); searchRenderValFn(searchSel,oSearchList,sInput); break; case 2: searchRenderFn(WT.G.P.symbolList[2],oSearchList); searchRenderValFn(searchSel,oSearchList,sInput); break; case 3: searchRenderFn(WT.G.P.symbolList[3],oSearchList); searchRenderValFn(searchSel,oSearchList,sInput); break; case 4: searchRenderFn(WT.G.P.symbolList[4],oSearchList); searchRenderValFn(searchSel,oSearchList,sInput); break; default: break; } if(selected){ if(selected == _e){ return; }else{ selected.cn('c_26 pt3l8 mt-5'); } } selected = _e; } _e = _e.pn(); } }); oSearchInput.evt('keyup',function(){//搜索框keyup var e=WT.e.fix(e),_e=e.t; var sInput = oSearchInput.val().toLow().trim(); if (e.kCode === 38) { if (selectedList) { if (selectedList.previousElementSibling) { selectedList.dc('bc_11'); selectedList = $(selectedList.previousElementSibling); selectedList.ac('bc_11'); selectedList.scrollIntoViewIfNeeded(); } } }else if (e.kCode === 40) { if (selectedList) { if (selectedList.nextElementSibling) { selectedList.dc('bc_11'); selectedList = $(selectedList.nextElementSibling); selectedList.ac('bc_11'); selectedList.scrollIntoViewIfNeeded(); } } }else if (e.kCode == 13) { if (selectedList) { var o = { val:selectedList.chr(0).h().replace(/<.+?>/g, ''), txt:selectedList.chr(1).h().replace(/<.+?>/g, '') }; if(cbFn){ cbFn(); }else{ WT.G._argsSearchBinding(o); } oSearch.r(); } }else{ searchRenderValFn(searchSel,oSearchList,sInput); } }); oSearchList.evt('mousedown',function(){//点击搜索列表 var e = WT.e.fix(e),_e = e.t; while(_e.tagName !== 'TABLE'){ if(_e.tagName === 'TR'){ _e.ac('bc_12'); var o = { val:_e.chr(0).h().replace(/<.+?>/g, ''), txt:_e.chr(1).h().replace(/<.+?>/g, '') }; if(cbFn){ cbFn(); }else{ WT.G._argsSearchBinding(o); } oSearch.r(); if(selectedList){ if(selectedList == _e){ return; }else{ selectedList.dc('bc_12'); } } selectedList = _e; } _e = _e.pn(); } }); } }
function searchRenderFn(items,oSearchList,isBengin){//重新渲染search结果 searchSel = items.map(function(item){ return { name:item.name, name_en:item.description }; }); if (isBengin) { oSearchList.h(laytpl(search_list_tlp.help()).render(searchSel)); selectedList = $(oSearchList.querySelector('tr:first-child')); selectedList.ac('bc_11'); } }
function searchRenderValFn(searchSel,oSearchList,sInput){ searchSel.forEach(function(item){ item.name = item.name.replace(/<.+?>/g, ''); item.name_en = item.name_en.replace(/<.+?>/g, ''); }); var _current = searchSel.filter(function(o){ return o.name.toLow().indexOf(sInput)>-1 || o.name_en.indexOf(sInput)>-1; }); _current.forEach(function(item){ item.name = item.name.replace(new RegExp(sInput, 'ig'), function(word){return '<font color="#15a7fa">' + word + '</font>'}); item.name_en = item.name_en.replace(new RegExp(sInput, 'ig'), function(word){return '<font color="#15a7fa">' + word + '</font>'}); }); oSearchList.h(laytpl(search_list_tlp.help()).render(_current)); selectedList = $(oSearchList.querySelector('tr:first-child')); selectedList.ac('bc_11'); }
q1:如果搜索列表中选中的文字和输入的文字相等,使选中文字变蓝。
在元素一加载时清楚所有标签
searchSel.forEach(function(item){
item.name = item.name.replace(/<.+?>/g, '');
item.name_en = item.name_en.replace(/<.+?>/g, '');
});
在元素过滤搜索时添加<font>标签
var _current = searchSel.filter(function(o){
return o.name.toLow().indexOf(sInput)>-1 || o.name_en.indexOf(sInput)>-1;
});
_current.forEach(function(item){
item.name = item.name.replace(new RegExp(sInput, 'ig'), function(word){return '<font color="#15a7fa">' + word + '</font>'});
item.name_en = item.name_en.replace(new RegExp(sInput, 'ig'), function(word){return '<font color="#15a7fa">' + word + '</font>'});
});
最后渲染查询结果,并让表格的第一列为选中元素,为keyup上下选择元素做打算。
oSearchList.h(laytpl(search_list_tlp.help()).render(_current));
selectedList = $(oSearchList.querySelector('tr:first-child'));
selectedList.ac('bc_11');
q2 上下键盘事件技巧,利用上一个或者下一个元素的兄的节点是否存在控制当前选中的元素,注意事件绑定在于是内部很容易重复绑定,使用完记得将事件remove掉。
if (e.kCode === 38) {
if (selectedList) {
if (selectedList.previousElementSibling) {
oSearchInput.blur();
selectedList.dc('bc_11');
selectedList = $(selectedList.previousElementSibling);
selectedList.ac('bc_11');
selectedList.scrollIntoViewIfNeeded();
}
}
}
if (e.kCode === 40) {
if (selectedList) {
if (selectedList.nextElementSibling) {
oSearchInput.blur();
selectedList.dc('bc_11');
selectedList = $(selectedList.nextElementSibling);
selectedList.ac('bc_11');
selectedList.scrollIntoViewIfNeeded();
}
}
}
q3 当前选中元素不再视野中时使用scrollIntoViewIfNeeded()
selectedList.scrollIntoViewIfNeeded();
q4 触发键盘上下键时要使输入框失去焦点,不然没法按上下键只能选中前两个元素
q5 (这个问题没解决)用户搜索时输入中文然后按回车变成英文,此刻自己写的keyup事件没有触发。
search问题补充:
1 对于keyup,keydown之类的事件要要使要绑定的元素处于focus状态,不然不会触发;事件绑定在input的keyup事件,在样式上控制页面当前选中的元素。
2 产生错误要一步步排查,要认真看代码是否有逻辑错误
3 小技巧当元素执行mouseenter事件时就是元素获取鼠标焦点