由於select標簽中的option條數較多,翻頁查詢比較麻煩,需要對select標簽進行優化,解決方法是通過增加模糊查詢功能來提高用戶體驗感。
優化后的界面如下:

在實現這個優化的過程中,參考了兩個開源的jQuery插件:comboSelect與select2;
select2:https://github.com/select2/select2/
comboSelect:https://github.com/PebbleRoad/combo-select
說明:
(一)comboSelect這個插件在2014就不再維護了,select2這個插件不僅可以實現單選擇模糊查詢,還可以實現多選擇模糊查詢。個人推薦使用select2。
(二)我在實現這個功能的過程中,剛開始考慮的是使用comboSelect這個插件,花了較多的時間來研究它,可是后面發現公司代碼集成了select2,因此最后選擇使用select2。
(三)講解一下comboSelect的底層實現原理。
comboSelect代碼解析:
(一)基本用法
首先在頁面中構建一個select,並初始化option數據,然后調用腳本
$("#selectId").comboSelect();
獲取option:selected的數據:
$(function() {
let value_selected;
$('select').comboSelect().change(function(){
value_selected = $(this).val();
alert(value_selected);
});
});
(二)底層原理
Combo Select在執行時,在原 select 外層套了一個 <div class=”combo-select”>,然后在select后面添加了三個element。
div.combo-arrow,是下拉箭頭
ul.combo-dropdown是用來顯示的下拉列表
input.combo-input 是用來輸入模糊搜索內容的輸入框
並通過修改原 select 的屬性,隱藏掉。

如果沒有引入相應的CSS文件進行修飾,可以很清楚的看到以上的結構。
(三)js數據模型
combo select初始化時,經過一系列代碼,最終構造幾個屬性:
$container : 生成一個新的div,將原來的select和新生成的ul等都放在其中。
$el : 初始的select element
$options : 所有的option 數據
$dropdown : 生成的 ul.combo-dropdown 對象
$items : 所有的options轉成 li 格式后的數據。
下圖是數據模型和html元素之間的對應關系。

(四)插件初始化
在js插件的代碼function Plugin ( element, options )會完成插件的初始化,根據select當前的數據,完成html元素的調整,以及js數據模型的初始化。初始化流程如下

(五)模糊查詢的邏輯
當用戶在input中輸入文字的時候,會觸發 keydown和keyup事件,在keyup事件中,對 $items中的數據依次進行匹配,設置 visible屬性,實現部分數據的展示。

在這個過程中,原始的select($el)及其所有的options($options)沒有變化,下拉列表的變化,主要是將ul.li($items)設置為可見或不可見。
最后相應的Demo文件我提交到了GitHub,可參考:https://github.com/JayInnn/search_select/tree/patch-1
