jQuery 生態雖豐富,但為單一自動完成功能引入巨大依賴庫得不償失。本文呈現一個純原生 JS 實現的輕量級自動完成插件,支援多 DOM 綁定隔離、鍵盤導航循環、本地陣列與 AJAX 遠端數據雙模式、中文輸入法相容,核心邏輯約 200 行,即插即用。
setInterval 輪詢 input.value 變化,繞過輸入法合成事件缺口。elemCSS.focus/blur 物件化定義高亮/常態樣式。;(function(window){
var autoComplete = function(o) {
var handler = (function(){
// 單實例處理器構造器
var Handler = function(e, o) { return new Handler.prototype.init(e, o); };
Handler.prototype = {
e: null, o: null, timer: null, show: 0,
input: null, popup: null,
init: function(e, o) { /* 綁定 DOM、註冊事件 */ },
match: function(quickExpr, value, source) { /* 本地過濾生成 <li> */ },
ajax: function(type, url, quickExpr, search) { /* XMLHttpRequest 遠端拉取 */ },
fetch: function(ajax, search, quickExpr) { /* 封裝 AJAX 參數 */ },
initEvent: function() { /* focus/blur/keydown/click 事件綁定 */ }
};
Handler.prototype.init.prototype = Handler.prototype; // jQuery 風格鏈式
return Handler;
})();
// 多 DOM 支援
if (this.length) {
for (var i = this.length - 1; i >= 0; i--) handler(this[i], o);
} else {
handler(this, o);
}
return this;
};
window.autoComplete = autoComplete; // 掛載全域
})(window);
input.onfocus:啟動 200ms 定時器輪詢值變化,動態重建提示列表。input.onblur:清除定時器,記錄當前值供下次聚焦恢復。<a> 綁定 click/focus/blur/keydown:點擊回填並關閉、焦點高亮、鍵盤導航(current 索引循環)。click 事件:點擊外部區域關閉面板(彌補 popup 無 onblur 缺陷)。var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
xhr.open(type, url + search, true); // 非同步
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = eval(xhr.responseText); // 期望回傳 JS 陣列字面量
that.match(quickExpr, search, data);
}
};
xhr.send(null);
安全提示:生產環境請以 JSON.parse 替代 eval,並嚴格驗證後端輸出格式。
var getElementsByClassName = function(searchClass, node, tag) {
node = node || document; tag = tag ? tag.toUpperCase() : "*";
if (document.getElementsByClassName) {
var temp = node.getElementsByClassName(searchClass);
if (tag === "*") return temp;
var ret = [];
for (var i = 0; i < temp.length; i++) if (temp[i].tagName === tag) ret.push(temp[i]);
return ret;
}
// 兼容舊瀏覽器 fallback 略
};
<div class="ac-wrap">
<input type="text" class="ac-input" />
<ul class="ac-popup"></ul>
</div>
<script>
var cities = ["北京", "上海", "廣州", "深圳", "杭州", "成都"];
document.getElementsByClassName("ac-wrap").autoComplete({
input: "input", popup: "ul",
source: cities, // 本地模式
// ajax: { type: "GET", url: "/api/suggest?q=" }, // 遠端模式
elemCSS: {
focus: { background: "#3399ff", color: "#fff" },
blur: { background: "#fff", color: "#000" }
}
});
</script>
零依賴、極簡體積、全場景覆蓋,適合對包體積敏感或不願引入重型框架的專案。原始碼結構清晰,易於二次擴展(如去抖優化、鍵盤無障礙、虛擬列表渲染大數據量)。