Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2447

打造更貼心的連動欄位網頁

$
0
0

在網頁設計中輸入欄位連動是很常見的情境,例如有員工編號及員工姓名兩個欄位,當使用者在輸入員工編號後,系統需自動帶出員工姓名。一般最直覺做法是利用<input>的onchange或onblur事件,在使用者輸入完成後送出AJAX呼叫向伺服器查詢後設定姓名欄位。程式範例如下: (展示)

<!DOCTYPEhtml>
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<title>傳統OnChange觸發</title>
<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js"></script>
<script>
        $(function () {
            $("#txtEmpNo").change(function () {
                $.get(
"DataSrc.ashx",
                    { key: $(this).val() },
function (res) {
                        $("#txtEmpName").val(res);
                    });
            });
        });
</script>
<style>
        .fld {
            width: 80px;
        }
</style>
</head>
<body>
員編: 
<inputid="txtEmpNo"class="fld"/>
<inputid="txtEmpName"readonlyclass="fld"style="background: #CCC"/>
<inputtype="button"value="查詢"/>
</body>
</html>

預期的操作流程是: 使用者輸入員工編號,右方灰底唯讀欄位帶出員工姓名供確認員編無誤,接著再按下查詢。

但是因為帶出姓名的邏輯放在change事件,使用者輸入124後,必須按Tab或點選其他網頁元素才會觸發AJAX呼叫。不熟操作的使用者,可能會在輸入完124後停止動作,卻苦等不到姓名出現,摸索一段時間才學到"多按一下Tab"的撇步。

為了改善操作流暢度,我們試著將查詢姓名的邏輯由onchange事件移到onkeyup按鍵事件,如此使用者按完鍵,毋需按Tab或點選其他欄位,系統就會直接帶出姓名。這種設計,應用於編號長度固定的情境還算完美,因為在keyup事件中可以檢查已輸入的文字長度,等待編碼完整再送出查詢。但若有效資料長度不一,就會產生困擾。例如: 在我們的範例程式中,1代表Transparent、11代表Blue、114代表Purple,於是在輸入114的過程,左側的欄位會依序冒出Transparent、Blue及Purple(見下方動畫展示),這意味著程式觸發了無效查詢,也干擾了使用者操作。(展示)

開發世界高手如雲,便有人想出巧妙解法 -- 使用者在輸入過程一般會先有連續打字的階段,輸入完畢後則會出現停頓,因此程式便可依按鍵間隔偵測使用者是否已輸入完畢,待全部輸入完畢後再送出查詢。透過這個技巧,電腦瞬間通人性,不需要多按鍵,又知道等輸入完成再查詢,提供更好的使用者體驗。

要使用JavaScript實踐構想並不困難,只需要在每次keyup事件時,不要直接送出AJAX,而是以window.setTimeout預定一段時間再送出(例如: 1秒),而在設定setTimeout時要留下識別,以便下次keyup時,先以clearTimeout清除上次預約的AJAX動作,再設定新的預約AJAX動作。如此,若按鍵後未滿一秒又按鍵,前次的AJAX查詢就會被取消,直到打完字停頓超過一秒沒按任何鍵,AJAX查詢才會真的送出。這段邏輯寫起來就會像下面這樣:

       $(function () {
var hnd;
            $("#txtEmpNo").keyup(
function () {
//取消前一次預定的查詢
                    window.clearTimeout(hnd);
//延遲一秒後才查詢,若這一段內又輸入其他字元
//則此一預約執行會被上一行程式取消
var value = $(this).val();
                    hnd = window.setTimeout(function () {
                        $.get(
"DataSrc.ashx",
                            { key: value },
function (res) {
                                $("#txtEmpName").val(res);
                            });
                    }, 1000);
            });
        });

操作過程如以下動畫所示,不需要額外Tab或點選,在輸入完成後又能自動帶出姓名,此種設計是不是更善解人意呢? (展示)

為了解說原理,我們剛才用setTimeout、clearTimeout自己造了輪子。但實務上不用這麼麻煩,網路已有現成Plugin可以實現前述構想,它有個術語叫Debounce(借用自電子學術語,指在接收訊息時避免發生誤動作的濾波機制),簡單列出幾個jQuery Plugin:

以下是改用doTimeout Plugin後的寫法: (展示)

        $(function () {
            $("#txtEmpNo").keyup(
function () {
                    $(this).doTimeout("findEmpName",
                        1000, function () {
                            $.get(
"DataSrc.ashx",
                                { key: $(this).val() },
function (res) {
                                    $("#txtEmpName").val(res);
                                });
                        });
            });
        });

學會這招,大家不妨檢視自己專案中採用onchange、onblur觸發AJAX連動欄位的場合,看看有無調整的需要,試著讓自己的網頁作品更貼心吧!


Viewing all articles
Browse latest Browse all 2447

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>