一般而言,只有表單元素與連結才能使用focus與blur事件,因此jQuery對於許多元素就歇菜了。但只要為元素節點設定一個tabindex屬性,非表單元素也可能使用這兩種事件。
但預設能使用焦時間點事件的元素一般也支援tabindex事件。為什麼這麼說呢?因為實質上,預設支援焦時間點事件的元素並不只這些,IE還預設body, frame, iframe, img, isIndex, object具有擷取失去焦點的能力。對於其他標準瀏覽器,它們之間還可能存在差異。因此我們不能單純地通過排除法,為非焦點元素添加tabindex屬性。而是轉而用一種更好的方法,通過檢測當前元素是否已經(顯式地或隱式地)設定了該屬性,才做進一步的操作。如下是檢測函數:
var hasAttr = function(el, name){ var attr = el.getAttributeNode && el.getAttributeNode(name); return attr ? attr.specified : false }
如果傳回值為false,我們就為該元素設定tabindex屬性。對於tabindex屬性,w3c對此也作出相應現範。如果tabindex為負數,那麼元素就不能使用tab鍵進行導航,但還能獲得焦點。如果位於 0 到 32767之間,則可以根據tabindex的值進行導航。如果當幾個元素的tabindex同為零時,則以文檔流的順序執行導航。更多與tabindex相關的資料,可以參看我的另一篇文章。
通過上面的分析,無疑將tabindex設為負數最安全,這樣就不會破壞原有的tab導航系統。順便一提,獲得焦點後,元素有一個虛線框,總有人挖空心思把它去掉。其實這無疑是對頁面易用性的踐踏,我們還要考慮一下某些特殊人群的需要,如不用滑鼠的高手,滑鼠壞了的可憐人或是視力有缺陷的人群。有文章介紹,去掉虛線框在美國是違法的,這是對視力障礙者的一種歧視!
下面給出完整的程式:
var hasAttr = function(el, name){ var attr = el.getAttributeNode && el.getAttributeNode(name); return attr ? attr.specified : false } var addEvent = function(obj,type,callback){ if ( obj.addEventListener ) { obj.addEventListener( type, callback, false ); } else if ( obj.attachEvent ) { obj.attachEvent( "on" + type, callback ); } } var focus = function(el,fn){ if(!hasAttr(el,"tabindex")) el.tabIndex = -1; addEvent(el,"focus",function(e){ fn.call(el,(e || window.event)); }); }
<br /><!doctype html><br /><html lang="zh-ch"><br /> <head><br /> <meta charset="utf-8" /><br /> <meta content="IE=8" http-equiv="X-UA-Compatible"/><br /> <title>讓元素擷取焦點 by 司徒正美</title></p><p> <script type="text/javascript"><br /> window.onload = function(){</p><p> var hasAttr = function(el, name){<br /> var attr = el.getAttributeNode && el.getAttributeNode(name);<br /> return attr ? attr.specified : false<br /> }<br /> var addEvent = function(obj,type,callback){<br /> if ( obj.addEventListener ) {<br /> obj.addEventListener( type, callback, false );<br /> } else if ( obj.attachEvent ) {<br /> obj.attachEvent( "on" + type, callback );<br /> }<br /> }<br /> var focus = function(el,fn){<br /> if(!hasAttr(el,"tabindex"))<br /> el.tabIndex = -1;<br /> addEvent(el,"focus",function(e){<br /> fn.call(el,(e || window.event));<br /> });<br /> }<br /> focus(document.getElementById("aaa"),function(e){<br /> alert(e.type)<br /> alert(this.innerHTML)<br /> });<br /> }<br /> </script><br /> <style type="text/css"><br /> body {<br /> padding:20px 100px;<br /> }<br /> a{<br /> color:#FFDEAD;<br /> }<br /> #aaa {<br /> padding:10px;<br /> width: 100px;<br /> height: 100px;<br /> background:#4DC2F2;<br /> color:#FF8C00;<br /> font-weight:bolder;<br /> }<br /> </style></p><p> </head><br /> <body><br /> <h1><a href="http://www.cnblogs.com/rubylouvre/archive/2010/05/03/1726334.html">讓元素擷取焦點</a></h1><br /> <div id="aaa" ><br /> 讓元素擷取焦點<br /> </div></p><p> </body><br /></html><br />
運行代碼