我正在編寫一個custom web component,這意味着互動。我如何告訴瀏覽器這個自定義組件應該獲得焦點?如何使自定義的Web組件成爲可聚焦的?
我希望我的自定義元素...
- 可以着重(通過選項卡的導航);
- 聚焦時可以接收按鍵;
- 可以匹配
:focus
pseudo-selector。
我沒有使用任何外部庫,只是普通的HTML5 APIs。
我正在編寫一個custom web component,這意味着互動。我如何告訴瀏覽器這個自定義組件應該獲得焦點?如何使自定義的Web組件成爲可聚焦的?
我希望我的自定義元素...
:focus
pseudo-selector。我沒有使用任何外部庫,只是普通的HTML5 APIs。
基於this demo我在this question發現,我有這樣的答案:
就在tabindex
屬性添加到您希望成爲焦點的元素。
// Add this to createdCallback function:
if (!this.hasAttribute('tabindex')) {
// Choose one of the following lines (but not both):
this.setAttribute('tabindex', 0);
this.tabIndex = 0;
}
// The browser automatically syncs tabindex attribute with .tabIndex property.
單擊該元素將使其焦點。按下標籤即可使用。在CSS中使用:focus
也可以。和keyup
事件工作,雖然keypress
不(但是it's deprecated anyway)。在Chrome 44和Firefox 40測試的
還要注意的是this.tabIndex
返回-1
即使HTML屬性丟失,但是這有一個不同的行爲不是設置tabindex="1"
:
<foo></foo>
:沒有tabindex
屬性,元素不可重點。<foo tabindex="-1"></foo>
:該元素無法通過製表符導航到達,但仍可通過單擊進行調整。參考文獻:
@Denilson,我想向您提供一些更多的信息。
如您所說,this.tabIndex = 0
適用於您的webcomponent不包含可調焦元素。如果確實如此,它會變得更加複雜。例如,如果您的組件包含一個或多個輸入,則首先「整個」組件獲得焦點,並且只有稍後當選項卡時,每個內部輸入逐個獲得焦點。這通常不是你想要的。通常,當組件獲得焦點時,這應該意味着它的第一個輸入立即得到焦點。
此外,還有一個反向標籤問題。如果您的第一個輸入具有焦點並且按下SHIFT-TAB鍵,則「整個」組件將獲得焦點,並且您不得不按兩次SHIFT-TAB鍵移動到上一個元素。
我發現這個解決所有焦點和Tab鍵的問題:
// At first, the component may get focus and accept tabbing.
createdCallback = function() { this.tabIndex = 0; }
// When the component gets focus, pass focus to the first inner element.
// Then make tabindex -1 so that the component may still get focus, but does NOT accept tabbing.
focus = function (e) { firstFocusableInnerElement.focus(); this.tabIndex = -1; }
// When we completely left the component, then component may accept tabbing again.
blur = function (e) { this.tabIndex = 0; }
注:截至目前(2015年9月),如果內部元件獲得焦點,那麼「整個」元素不匹配:focus
僞選擇器(僅在Chrome中測試)。如果發現這種行爲只是錯誤的。焦點事件被解僱,模糊事件不是。所以元素應該有重點,對吧?我希望他們在未來改變這一點。
我想這是有效的,因爲當一個內部元素被聚焦(或失去焦點)時,事件本身起泡,調用你的處理程序。而......如果外部元素不可聚焦,那麼行爲是什麼?內在的也是可以聚焦的嗎?你有任何現場演示可用嗎? –
Shadow DOM有一個稱爲「事件重定向」的功能,當事件的目標氣泡向上時,它會改變事件的目標,使得目標總是在接收元素的光線DOM中。 即,源自影子DOM內的節點的事件被重定向,以使它們看起來來自影子主機。 如果元素已具有焦點,則內部元素的焦點事件不會越過邊界。 – MarcG
在此處查看我的實時演示:http://jsbin.com/gimomahazi/edit?html,console,output – MarcG