今天在處理jQuery自動完成時遇到一個問題。就以jQuery自動完成懶人包的例子說起: 在findValue(li)中,使用了Hard-Coding的方式將額外的值填到txtSymbol及txtCName:

function findValue(li) {
    if (li == null) return alert("No match!");
    $("#txtSymbol").val(li.extra[0]);
    $("#txtCName").val(li.extra[1]);
}

如果網頁有txtSymbol1及txtSymbol2兩個輸入欄位都掛了自動完成,當findValue被呼叫時,要如何得知使用者是在txtSymbol1還是txtSymbol2裡輸入文字? 得到的結果該填到txtCName1還是txtCName2?

我們查看jquery.autocomplete.js,可以看到onItemSelected的觸發過程如下:

if (options.onItemSelect)
    setTimeout(function () { options.onItemSelect(li) }, 1);

有個解法是將input元素本身當成findValue的第二個參數傳進去;但還有另一種思維,若在findValue中可以用this來代表目前操作的元素,豈不是更符合jQuery事件的概念? 記得以前介紹過的this與ClosureJavascript .apply()嗎? 這就是一個蠻適當的應用場合。

於是我們將程式碼改成:

if (options.onItemSelect)
    setTimeout(function () { options.onItemSelect.call($input[0], li); }, 1);

然後,findValue就可以寫成:

function findValue(li) {
    if (li == null) return alert("No match!");
    $(this).val(li.extra[0]).next().val(li.extra[1]);
}

是不是寫起來蠻直覺呢?


Comments

# by QiQiBoY

看不大明白,留名了。。。

Post a comment