js、jquery實(shí)現(xiàn)列表模糊搜索功能過程解析
實(shí)現(xiàn)的搜索功能:
1. 可以匹配輸入的字符串找出列表中匹配的項(xiàng),列表框的高度跟隨搜索出的列表項(xiàng)的多少改變
2. 可以點(diǎn)擊某一項(xiàng)進(jìn)行選中列表項(xiàng)
3. 可以按下上、下、回車鍵來控制列表項(xiàng)
4. 按下回車鍵時(shí)則會(huì)選中列表項(xiàng)
5. 點(diǎn)擊文本框中的下拉鍵頭時(shí)會(huì)切換下拉框的顯示/隱藏
6. 點(diǎn)擊文本框外部時(shí)自動(dòng)隱藏下拉框
先來預(yù)覽一下效果吧!
列表中包含的列表項(xiàng)有:
北京、上海、杭州、安慶、大興安嶺、安陽、廣州、貴陽、哈爾濱、合肥、邯鄲、呼倫貝爾、淮南、黃山、濟(jì)南、濟(jì)寧、嘉興、南昌、南通、南寧、南京
在預(yù)覽時(shí)需要輸入匹配以上項(xiàng)目的文字,以便更好的預(yù)覽效果

具體的代碼實(shí)現(xiàn)
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>js、jquery實(shí)現(xiàn)列表模糊搜索功能</title>
<script src="https://lib.baomitu.com/jquery/3.4.1/jquery.js"></script>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
h2 {
margin-bottom: 20px;
}
#container {
width: 500px;
text-align: center;
margin: 0 auto;
font-family: "微軟雅黑";
margin-top: 50px;
}
.selectContainer {
position: relative;
}
.selectInput {
width: 200px;
height: 25px;
border-style: none;
border: 1px solid #999;
border-radius: 3px;
padding: 0 3px;
}
.picture_click {
background: url(img/select-default.png) no-repeat;
opacity: 1;
width: 15px;
height: 8px;
position: absolute;
top: 10px;
right: 125px;
}
.picture_click:hover {
background-image: url(img/select-hover.png);
}
.selectList {
width: 206px;
height: 212px;
overflow-y: scroll;
text-align: left;
margin: 0 172px;
border: 1px solid #999;
display: none;
position: relative;
}
.selectList div {
cursor: pointer;
}
</style>
</head>
<body>
<div id="container">
<h2>模糊搜索</h2>
<div id="cityContainer" class="selectContainer">
<label>城市:</label>
<input type="text" placeholder="請輸入城市名稱" list="cityList" class="selectInput" name="cityName" id="cityName" value="" onfocus="fuzzySearch.call(this)" />
<div class="picture_click dropDowns" style=""></div>
<div id="cityList" class="selectList">
<div id="001">北京</div>
<div id="002">上海</div>
<div id="003">杭州</div>
<div id="004">安慶</div>
<div id="005">大興安嶺</div>
<div id="006">安陽</div>
<div id="007">廣州</div>
<div id="008">貴陽</div>
<div id="009">哈爾濱</div>
<div id="010">合肥</div>
<div id="011">邯鄲</div>
<div id="012">呼倫貝爾</div>
<div id="013">淮南</div>
<div id="014">黃山</div>
<div id="015">濟(jì)南</div>
<div id="016">濟(jì)寧</div>
<div id="017">嘉興</div>
<div id="018">南昌</div>
<div id="019">南通</div>
<div id="020">南寧</div>
<div id="021">南京</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
//初始化下拉框
initSearchInput();
function fuzzySearch(e) {
var that = this;
//獲取列表的ID
var listId = $(this).attr("list");
//列表
var list = $('#' + listId + ' div');
//列表項(xiàng)數(shù)組 包列表項(xiàng)的id、內(nèi)容、元素
var listArr = [];
//遍歷列表,將列表信息存入listArr中
$.each(list, function(index, item){
var obj = {'eleId': item.getAttribute('id'), 'eleName': item.innerHTML, 'ele': item};
listArr.push(obj);
})
//current用來記錄當(dāng)前元素的索引值
var current = 0;
//showList為列表中和所輸入的字符串匹配的項(xiàng)
var showList = [];
//為文本框綁定鍵盤引起事件
$(this).keyup(function(e){
//如果輸入空格自動(dòng)刪除
this.value=this.value.replace(' ','');
//列表框顯示
$('#' + listId).show();
if(e.keyCode == 38) {
//up
console.log('up');
current --;
if(current <= 0) {
current = 0;
}
console.log(current);
}else if(e.keyCode == 40) {
//down
console.log('down');
current ++;
if(current >= showList.length) {
current = showList.length -1;
}
console.log(current);
}else if(e.keyCode == 13) {
//enter
console.log('enter');
//如果按下回車,將此列表項(xiàng)的內(nèi)容填充到文本框中
$(that).val(showList[current].innerHTML);
//下拉框隱藏
$('#' + listId).hide();
}else {
//other
console.log('other');
//文本框中輸入的字符串
var searchVal = $(that).val();
showList = [];
//將和所輸入的字符串匹配的項(xiàng)存入showList
//將匹配項(xiàng)顯示,不匹配項(xiàng)隱藏
$.each(listArr, function(index, item){
if(item.eleName.indexOf(searchVal) != -1) {
item.ele.style.display = "block";
showList.push(item.ele);
}else {
item.ele.style.display = 'none';
}
})
console.log(showList);
current = 0;
}
//設(shè)置當(dāng)前項(xiàng)的背景色及位置
$.each(showList, function(index, item){
if(index == current) {
item.style.background = "#eee";
$('#' + listId).scrollTop(item.offsetTop);
}else {
item.style.background = "";
}
})
//設(shè)置下拉框的高度
//212為列表框的最大高度
if(212 > $('#' + listId + ' div').eq(0).height() * showList.length) {
$('#' + listId).height($('#' + listId + ' div').eq(0).height() * showList.length);
}else {
$('#' + listId).height(212);
}
})
}
function initSearchInput() {
//給下拉箭頭綁定點(diǎn)擊事件 點(diǎn)擊下拉箭頭顯示/隱藏對應(yīng)的列表
//輸入框的類名為selectInput
//下拉箭頭的類名為picture_click、dropDowns
//下拉列表的類名為selectList
for(var i = 0; i < $('.picture_click').length; i++) {
$('.picture_click').eq(i).click(function(){
$(this).parent().find('.selectList').toggle();
})
}
//為列表中的每一項(xiàng)綁定鼠標(biāo)經(jīng)過事件
$('.selectList div').mouseenter(function(){
$(this).css("background", "#eee").siblings().css("background", "");
});
//為列表中的每一項(xiàng)綁定單擊事件
$('.selectList div').click(function(){
//文本框?yàn)檫x中項(xiàng)的值
$(this).parent().parent().find('.selectInput').val($(this).html());
//下拉框隱藏
$(this).parent().hide();
});
//點(diǎn)擊下拉框外部的時(shí)候使下拉框隱藏
var dropDowns = document.getElementsByClassName('dropDowns');
var selectList = document.getElementsByClassName('selectList');
document.body.onclick = function(e){
e = e || window.event;
var target = e.target || e.srcElement;
for(var i = 0; i < dropDowns.length; i++) {
if(target != dropDowns[i] && target != selectList[i]){
selectList[i].style.display = 'none';
}
}
}
}
</script>
</html>
需要注意的地方:
1. 使用此方法時(shí),需要給輸入框加類名selectInput,給下拉剪頭加類名picture_click、dropDowns,給列表框加類名selectList;
2. 輸入框需要有l(wèi)ist屬性,list屬性對應(yīng)的值為列表框的id值
3. 需要給文本框綁定事件,onfocus="fuzzySearch.call(this)",(由于自定義的函數(shù)中,this指向的是window,所以需要通過call方法改變this指向,即指向該文本框,以便在方法中使用)
4. 在實(shí)現(xiàn)搜索功能的過程中,遇到一點(diǎn)小問題,就是在獲取列表項(xiàng)的offersetTop時(shí),獲取的是28,找不出原因,最終通過查閱相關(guān)資料終于解決,即想要獲取子元素的offsetTop,則需要給父元素設(shè)置相對定位,才能獲取到正確的offsetTop。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS倒計(jì)時(shí)實(shí)例_天時(shí)分秒
下面小編就為大家?guī)硪黄狫S倒計(jì)時(shí)實(shí)例_天時(shí)分秒。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
解決javascript:window.close()在chrome,Firefox下失效的問題
本篇文章是對javascript:window.close()在chrome,Firefox下失效問題的解決方法進(jìn)行了分析介紹。需要的朋友參考下2013-05-05

