The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

利用 jQuery 將 DOM 元素聚焦 focus() 的六個版本

簡單的東西不簡單,將 DOM 元素聚焦是個再簡單不過的功能了,在實務上也經常用到,但是我們最近在使用 FancyBox 利用 IFRAME 載入頁面時卻怎麼樣都無法讓游標自動停在特定的文字輸入框中,除此之外,我也將我這些年累積遇到無法 focus() 的問題做了一次總整理,一共有六個版本之多。

第一種:經典版 

$('#Account').focus();

潛在的問題可以從官方提供的 Events/focus 文件看出一些端倪,但大部分的情況還是可以正常運作的,這也是讓 Web 開發人員匪夷所思的地方,就是有些地方可以用、有些地方不能用。

jQuery Events/focus: This causes all of the functions that have been bound to the focus event to be executed. Note that this does not execute the focus method of the underlying elements.

第二種:轉換成 DOM 去執行 focus() 函式

$('#Account')[0].focus();

使用 DOM 執行有很多風險,如果例外處理沒做好就很容易出現以下問題:

This webpage contains errors that might prevent it from displaying or working correctly. If you are not testing this webpage, click No.  Error: '0' is null or not an object

'0' 是 null 或不是一個物件

第三種:轉換成 DOM 去執行 focus() 函式,外加條件判斷確保執行無誤

if($('#Account').length > 0) { $('#Account')[0].focus(); }

你以為這樣就沒事了嗎?錯!因為當元素處於「隱藏」狀態時,是無法執行 DOM 物建的 focus() 函式的,硬要去執行就會出現以下錯誤:

Error: Can't move focus to the control because it is invisible, not enabled, or of type that does not accept focus

控制項不可見、為啟動或無法接受焦點,因此無法將焦點移到控制項上。

第四種:轉換成 DOM 去執行 focus() 函式,外加條件判斷確保執行無誤,以及利用 setTimeout 修正笨 IE 的詭異錯誤

if ($('#Account').length > 0) { setTimeout(function() { $('#Account')[0].focus(); }, 0); }

這問題會出現在 IE8 之前的 IE 瀏覽器上,通常發生在 DOM 元素先被隱藏,然後才被顯示出來 (這是常用的 hack 技法),雖然 DOM 元素已經在畫面上看的到,但 DOM 物件狀態還沒改變,導致執行 focus() 函式發生錯誤,這時就要用以上程式來解決。

第五種:轉換成 DOM 去執行 focus() 函式,外加條件判斷確保執行無誤,以及利用 setTimeout 修正笨 IE 的詭異錯誤,以及利用 try/catch 將最後可能潛在出現的問題給過濾掉。

if($('#Account').length>0){setTimeout(function(){try{$('#Account')[0].focus();}catch(e){}},0);}

以上應該算是我的終極解決版了,但不完美,所以我設計了第六個版本。

第六種:最終完美版

$('#Account').setfocus();

最後我將這些經驗濃縮成一個 jQuery 外掛 (Plugins),讓全網站有需要用到 focus() 功能的地方都可以利用 jQuery 自訂外掛函式達成目的。原始碼如下:

(function($)
{
    jQuery.fn.setfocus = function()
    {
        return this.each(function()
        {
            var dom = this;
            setTimeout(function()
            {
                try { dom.focus(); } catch (e) { } 
            }, 0);
        });
    };
})(jQuery);

 

對於剛從事 Web 甚或從事 Web 開發一段時間的人來說,真的很難想像能遭遇到多少大大小小、龜龜毛毛的的問題,但我卻還是不時會聽到有人說:「做網站很簡單阿,隨便一個大學生都可以做了」這樣的話,每次都是冷靜的想一想後決定:算了,這真的不是三言兩語講的清楚的,就讓誤解繼續下去吧~~

 

相關連結