【发布时间】:2016-08-20 23:44:45
【问题描述】:
我最近在跨浏览器测试时遇到了 React 的问题。在包含 React 自动生成的 <span> 标签的元素上调用 focus() 时会出现此问题。
简化组件
我的组件 <Button/> 是普通 <button> 的抽象,具有附加功能。这是一个简化版:
输出:
<Button value="Button"/>
是:
<button><span>Button</span></button>
由于 React 在跨度中自动包装浮动文本节点,因此它可以分配 data-reactid,<button> 内的文本被包装在 <span> 标记中。
按钮有一个onClick() 方法来调用元素上的event.target.focus()。
问题
在 Chrome/Firefox 中单击按钮会将焦点设置在按钮上。在 Safari 中,单击按钮并不总是将焦点设置在按钮上。相反,<body> 接收焦点。
经过几个小时的摆弄,我发现该按钮只有在 React 自动生成的 <span> 标签(下方按钮的蓝色区域)之外单击时才会获得焦点。点击由 React 创建的 <span> 标签(下方按钮的黑色区域)将导致 <body> 获得焦点。
同样,这只发生在 Safari 中。
在 Chrome/Firefox 中,单击任一区域都会导致 <button> 获得焦点。
这是一个 CodePen 包含完整示例,重现步骤:
- 在 Safari 中打开 the CodePen。
- 打开您的控制台。
- 单击按钮,在黑暗区域(对应于
<span>标签)。您会注意到focused元素(使用document.activeElement)很可能是<body>。 - 单击蓝色区域内的按钮(对应于
<button>标记。您会注意到focused元素是<button>。
问题
是否有一种首选方法可以使浏览器之间的行为保持一致?还是这与 React 无关,而仅仅是 Safari/Chrome/Firefox 处理 focus() 的方式不同?
一种可能的解决方案:在内部 <span> 元素上设置 pointer-events: none;。这将允许对<span> 的点击传播到<button>。然而,这似乎很骇人听闻。
【问题讨论】:
标签: javascript google-chrome reactjs safari