首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

原生 JavaScript 實現輸入自動完成插件:零依賴、多實例隔離、中文友好

     編輯:J2EE

jQuery 生態雖豐富,但為單一自動完成功能引入巨大依賴庫得不償失。本文呈現一個純原生 JS 實現的輕量級自動完成插件,支援多 DOM 綁定隔離、鍵盤導航循環、本地陣列與 AJAX 遠端數據雙模式、中文輸入法相容,核心邏輯約 200 行,即插即用。

核心功能清單

  • 即時過濾:輸入字符前綴匹配提示項。
  • 鍵盤交互:上下鍵選擇、循環焦點、Tab/Shift+Tab 關閉面板。
  • 雙數據源:靜態陣列綁定 / AJAX 動態請求(同步/非同步可配)。
  • 多實例隔離:同頁多輸入框綁定不同數據源,互不干擾。
  • 中文相容: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);

關鍵實現細節

1. 事件模型

  • input.onfocus:啟動 200ms 定時器輪詢值變化,動態重建提示列表。
  • input.onblur:清除定時器,記錄當前值供下次聚焦恢復。
  • 提示項 <a> 綁定 click/focus/blur/keydown:點擊回填並關閉、焦點高亮、鍵盤導航(current 索引循環)。
  • 文檔級 click 事件:點擊外部區域關閉面板(彌補 popup 無 onblur 缺陷)。

2. AJAX 封裝

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,並嚴格驗證後端輸出格式。

3. 通用工具函數

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>

總結

零依賴、極簡體積、全場景覆蓋,適合對包體積敏感或不願引入重型框架的專案。原始碼結構清晰,易於二次擴展(如去抖優化、鍵盤無障礙、虛擬列表渲染大數據量)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved