添加 tabindex='-1' 屬性;
預設:擷取不到焦時間點事件(blur)
1 |
< div class = "wl-product" id = "wl-product" ></ div > |
可以擷取焦時間點事件(blur)
1 |
< div class = "wl-product" id = "wl-product" tabindex = '-1' ></ div > |
具體詳解:
先看:W3C關於onfocus的部分
The onfocus event occurs when an element receives focus either by the pointing device or by tabbing navigation.
This attribute may be used with the following elements: A, AREA, LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.
再看:Tabbing navigation的部分
Those elements that do not support the tabindex attribute or support it and assign it a value of "0" are navigated next. These elements are navigated in the order they appear in the character stream.
以下來自互連網:
【focus和tabIndex】
在KeyBind程式中,除了綁定對象的keydown事件,還不夠的,可以在ff測試下面的代碼:
< div style ="width:100px; height:100px; background-color:#CCC;" onkeydown ="alert(1)" ></ div >
無論怎樣都觸發不了onkeydown事件(ie可以觸發),那就奇怪了,按照一般的思路應該是可以的啊。
這個可以從w3c關於KeyboardEvent的部分中找到原因:
Keyboard events are commonly directed at the element that has the focus.
大概就是說鍵盤按鍵事件一般指向能擷取焦點的元素,就是不能擷取焦點的元素就不能觸發鍵盤按鍵事件了。
難道div就不能擷取焦點?用下面的代碼測試(ff):
< div id ="test" style ="width:100px; height:100px; background-color:#CCC;" onfocus ="alert(1)" ></ div >
< script > document.getElementById( " test " ).focus(); </ script >
還真的不行,那問題就在於怎麼使div能擷取焦點了(當然這個是轉了不少彎才想出來的)。
最後發現給元素設定tabIndex就能讓元素能擷取焦點了,如果不需要詳細瞭解的話下面可以略過。
首先看看w3c關於onfocus的部分:
The onfocus event occurs when an element receives focus either by the pointing device or by tabbing navigation.
This attribute may be used with the following elements: A, AREA, LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.
當元素通過指定(點擊)或tab導航(Tabbing navigation)獲得焦點,onfocus事件就會觸發。
該屬性會使用在以下元素(就是說預設可以擷取焦點的元素):A, AREA, LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.
測試下面的代碼:
< a href = " # " onfocus = " alert(1) " onkeydown = " alert(2) " > focus < / a>
果然兩個事件都可以執行。
接著看Tabbing navigation的部分:
Those elements that do not support the tabindex attribute or support it and assign it a value of "0" are navigated next. These elements are navigated in the order they appear in the character stream.
這裡看得不太明白,關鍵的意思是給元素設定tabindex為0就可以被導航到了(能擷取焦點了)。
測試下面的代碼(ff):
< div tabindex = " 0 " style = " width:100px; height:100px; background-color:#CCC; " onfocus = " alert(1) " onkeydown = " alert(2) " >< / div>
果然兩個事件都能觸發了。
不過w3c說得很模糊,msdn上倒是很清楚:
An element can have focus if the tabIndex property is set to any valid negative or positive integer.
Elements that receive focus can fire the onblur and onfocus events as of Internet Explorer 4.0, and the onkeydown, onkeypress, and onkeyup events as of Internet Explorer 5.
只要元素的tabIndex屬性設定成任何有效整數那麼該元素就能取得焦點。元素在取得焦點後就能觸發onblur,onfocus,onkeydown, onkeypress和onkeyup事件。
不同tabIndex值在tab order(Tabbing navigation)中的情況:
Objects with a positive tabIndex are selected in increasing iIndex order and in source order to resolve duplicates.
Objects with an tabIndex of zero are selected in source order.
Objects with a negative tabIndex are omitted from the tabbing order.
tabIndex值是正數的對象根據遞增的值順序和代碼中的位置順序來被選擇
tabIndex值是0的對象根據在代碼中的位置順序被選擇
tabIndex值是負數的對象會被忽略
這個不知道是否符合標準,但貌似ff跟ie是一樣的(不同的地方後面會說)。
那麼設定一個負的tabIndex值應該是最理想的了。
ps:如果對ff的tabindex有興趣的話,推薦看看Test cases for tabindex bugs in Firefox,裡面有更詳細更專業的分析。
那ie通過一開始的測試,是不是就說明不需要了呢?我們換一個元素測試:
< ul style = " width:100px; height:100px; background-color:#CCC; " onfocus = " alert(1) " onkeydown = " alert(2) " >< / ul>
換成ul就又不能觸發事件了,怎麼搞的。
再看看msdn,裡面有一段:
The following elements can have focus by default but are not tab stops. .略. applet, div, frameSet, span, table, td.
下面的元素預設能擷取焦點但不能tab導航:applet, div, frameSet, span, table, td.
看來ie真是“為程式員著想”,但其他元素總不能漏了啊,還是全部都設定tabIndex好了。
終於回到程式上來,首先設定tabIndex:
o.tabIndex = - 1 ;
ff元素獲得焦點後會出現一個虛線框,去掉會美觀一點:
isIE || (o.style.outline = " none " );
ps:如果tabIndex設為0或以上的話ie也會出現虛線框。
綁定了keydown之後,點擊一下容器(擷取焦點)後就能用方向鍵控制方向了,但如果(沒有獲得焦點時)點擊滑塊,還是觸發不了事件。
因為滑塊在拖動效果中ie的滑鼠捕獲和ff的取消預設動作導致容器不能獲得焦點,那手動設定可以嗎?
是可以的,ff中就是直接在滑塊的mousedown事件中執行容器的focus方法獲得焦點。
ie本來也是可以的,但ie中當對象執行focus方法時,如果該對象有部分在捲軸外就會自動滾動到適當的位置(還好點擊不會這樣)。
為了降低影響,程式中把滑塊也綁定了鍵盤控制,這樣點擊滑塊時只要執行滑塊的focus方法獲得焦點就可以了:
var oFocus = isIE ? ( this .KeyBind( this .Bar), this .Bar) : this .Container;
addEventHandler( this .Bar, " mousedown " , function (){ oFocus.focus(); });
ps:由於focus並不會冒泡(w3c標準),所以不用擔心滑塊的focus導致容器獲得焦點。
ps2:w3c的文檔還真是難讀,還是msdn的易懂。