我正在编写一个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