上回提過因使用IE自動完成造成onchange事件不被觸發的問題,著實帶來一些困擾,不少User抱怨系統掛在onchange事件的欄位連動功能失效。雖然User漸漸都已學會在這些欄位使用手工輸入,不要依賴IE自動完成帶入結果就可以避開問題,抱怨日少。不過我想從網頁設定上去停用autocomplete還是比較根本的解決之道。

當然,我們可以抱著寧可錯殺一百,不可錯放一個的精神來個$("input:text").attr("autocomplete", "off"),把網頁上所有<input type='text'>的自動完成功能全都閹掉,一了百了。不過,我習慣處理得細膩一點,將這個不得已措施的範圍縮小到受影響的欄位上,換句話說,只有掛了onchange事件的<input type='text'>才是要撲殺的對象。

要怎麼偵錯欄位是否有掛onchange事件? 想起上回剛好玩過列舉元素已掛載的jQuery事件的小把戲,這回把它融合進來,就做出了這個"標靶治療式"的autocomplete屬性停用Plugin。

以下的程式範例可以讓大家拿去Mini jQuery Lab實地玩一下。

//針對有掛onchange的<input type="text">設定autocomplete="off"
//參考: http://tinyurl.com/yzwp3lt
//限制: 只對執行當下已經掛載onchange事件者有效(不包含.live()掛載者)
$.fn.disableAutoCompleteForChange = function(force) {
    //過濾只留下<input type='text'>
    return this.filter(":text").each(function() {
        //篩選有掛change事件者, 參考: http://tinyurl.com/yka6x8g
        var evts = $.data(this, "events");
        if (force || evts && evts["change"] || this.onchange != undefined)
            $(this).attr("autocomplete", "off");
            //.val("SET"); //可加上這段測試是否被設定
    });
}
//加入三個<input>進行測試, T2用jQuery掛onchange, T3直接宣告onchange
$("body").append("<input id='T1' /><input id='T2' />")
.append("<input id='T3' onchange='alert(3);' />");
$("#T2").change(function() { alert("2"); });
$("input").disableAutoCompleteForChange();

注意:

  1. .disableAutoCompleteForChange()的呼叫時機要在onchange掛上去後
  2. 對使用.live()掛載的onchange無效
  3. 另外多加對以<input onchange="..." />方式掛上事件的偵測
  4. .disableAutoCompleteForChange(true)時可不管有無onchange,一律停用
[2010-03-08補充] 測試發現使用jQuery 1.4+掛載change()事件即可解決此問題

Comments

# by 91

酷! 不過小的那邊要說服使用者, 為什麼有一些有自動完成功能,有一些沒有, 就比較難跟使用者說明了... 對他們來說,似乎很難懂啥叫onchange :P

# by Jeffrey

to 91, 意外發現,這問題被jQuery 1.4秒殺了。(http://bit.ly/aLOD7j)

Post a comment