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

ASP.NET 實作百度風格搜尋下拉提示:隱藏按鈕觸發 Postback + ListBox 鍵盤導航

     編輯:ASP.NET 基礎

需求與挑戰

輸入框輸入時即時顯示建議清單,**不使用 AJAX/UpdatePanel**,而是利用**隱藏按鈕觸發完整 Postback**,再由 `ListBox` 原生鍵盤支援 (上下鍵選擇) 回填輸入框。這在早期 ASP.NET (無 AJAX 擴充) 環境是常見變通方案。

核心架構

[輸入框 oninput/onpropertychange] → [JS 觸發隱藏按鈕 click] → [Postback → btnHelp_Click 查詢綁定 ListBox]
                                      ↑_______________________________|
                                      ListBox SelectedIndexChanged 回填輸入框

ASPX 完整代碼

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
    <title>搜尋建議 Demo</title>
    <script type="text/javascript">
        // 1. 輸入框值變化 → 觸發隱藏按鈕 Postback
        function TriggerSearch() {
            var btn = document.getElementById("<%= btnHelp.ClientID %>");
            if (btn) btn.click();
        }

        // 2. 鍵盤上下鍵 → 讓 ListBox 取得焦點 (原生支援上下鍵選擇)
        function HandleKeyDown(e) {
            e = e || window.event;
            // 38=Up, 40=Down
            if (e.keyCode === 38 || e.keyCode === 40) {
                var lst = document.getElementById("<%= lst.ClientID %>");
                if (lst) lst.focus();
            } else {
                // 其他鍵讓輸入框保持焦點
                document.getElementById("<%= inpContent.ClientID %>").focus();
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            輸入關鍵字:
            <br />
            <input runat="server" id="inpContent"
                oninput="TriggerSearch()"
                onpropertychange="TriggerSearch()"
                onkeydown="HandleKeyDown(event)" />
            <br />
            <asp:ListBox runat="server" ID="lst" AutoPostBack="true"
                OnSelectedIndexChanged="lst_SelectedIndexChanged"
                Style="display:none; position:absolute; z-index:100;" />
            <asp:Button runat="server" ID="btnHelp" Text="隱藏按鈕"
                OnClick="btnHelp_Click" Style="display:none;" />
        </div>
    </form>
</body>
</html>

後端 C# 代碼

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // 確保按鈕隱藏 (display:none 不會輸出到頁面導致 JS 找不到)
        btnHelp.Style["display"] = "none";
    }

    // 隱藏按鈕 Click:查詢資料並綁定 ListBox
    protected void btnHelp_Click(object sender, EventArgs e)
    {
        string keyword = inpContent.Value.Trim();
        // 模擬資料來源
        var allData = new[] { "apple", "application", "banana", "band", "cat", "cater", "dog", "door" };

        lst.Items.Clear();
        int idx = 0;
        foreach (var item in allData)
        {
            if (item.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                lst.Items.Add(new ListItem(item, idx.ToString()));
                idx++;
            }
        }

        if (lst.Items.Count > 0)
        {
            lst.Style["display"] = "block";
            lst.SelectedIndex = 0; // 預選第一項
        }
        else
        {
            lst.Style["display"] = "none";
        }

        // 焦點回輸入框,方便繼續輸入
        ScriptManager.RegisterStartupScript(this, GetType(), "focusInput", 
            "$get('" + inpContent.ClientID + "').focus();", true);
    }

    // ListBox 選項變更 (鍵盤上下鍵或滑鼠點擊) → 回填輸入框
    protected void lst_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (lst.SelectedIndex >= 0)
        {
            inpContent.Value = lst.SelectedItem.Text;
            lst.Style["display"] = "block"; // 保持顯示
            // 焦點留在 ListBox 方便繼續上下鍵
            ScriptManager.RegisterStartupScript(this, GetType(), "focusList", 
                "$get('" + lst.ClientID + "').focus();", true);
        }
    }
}

關鍵技術點

技術點說明
`oninput` + `onpropertychange`跨瀏覽器偵測輸入框值變化 (IE 專用 `onpropertychange`)
隱藏按鈕 `display:none`不可用 `Visible=false` (不會渲染),需用 CSS 隱藏讓 JS 能 `getElementById`
`ListBox.AutoPostBack=true`選項變更自動 Postback 觸發 `SelectedIndexChanged`
焦點管理Postback 後用 `ScriptManager.RegisterStartupScript` 恢復焦點,否則輸入框失焦體驗極差
鍵盤導航上下鍵 (38/40) 轉移焦點至 ListBox,利用原生行為避免自行實作選項高亮

缺點與現代替代方案

  • **完整 Postback**:頁面閃爍、ViewState 開銷大、輸入頻繁時伺服器壓力大。
  • **焦點跳動**:Postback 導致焦點丟失,需 JS 強制恢復,體驗不如 AJAX 平滑。
  • **無防抖**:每次按鍵皆觸發請求,建議前端加 `setTimeout` 防抖 (200-300ms)。

**現代做法**:
1. **jQuery UI Autocomplete / Select2 / Typeahead.js** + **WebMethod/PageMethod/WebAPI** 回傳 JSON。
2. **ASP.NET Core** + **Fetch API** + **輸入防抖** + **虛擬滾動大清單**。
3. 若必須 WebForms:用 `UpdatePanel` 包裹 ListBox + `AsyncPostBackTrigger` 實現局部更新,但仍建議遷移至 AJAX 方案。

總結

「隱藏按鈕 + ListBox」是 WebForms 早期無 AJAX 環境下的巧妙變通,**利用原生控件 Postback 機制與 ListBox 鍵盤支援** 實現下拉提示。理解此模式有助於維護舊系統;新專案請直接採用前端元件庫 + AJAX/JSON 方案。

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