专注于跨源iframe

时间:2019-03-01 23:00:37

标签: javascript iframe focus

我有一个网络应用,该应用在iframe中具有嵌入式视频,通常来自跨来源(例如YouTube)。我目前将重点放在window上以进行记录。但是,由于iframe不是window的子级,因此当用户单击iframe时,window会模糊,尽管用户仍在查看页面,但仍会停止我的日志。如何跟踪焦点到此跨域iframe?

1 个答案:

答案 0 :(得分:0)

tl; dr-您无法(至少不能直接)将注意力集中在iframe上。但是还有其他有用的信息来源。

由于iframe是跨域的,因此立即排除了直接访问其焦点状态,附加任何事件处理程序或发布任何消息的可能性。但是,您可以使用document.body.activeElement来查看用户是否单击了iframe,而不是另一个选项卡/窗口。有了这些知识,就可以进行这种破解:

const handleLeave = () => {
  const { activeElement } = document;
  const iframeIsActiveElement = activeElement && activeElement.tagName === 'IFRAME';

  if (iframeIsActiveElement) {
    // timeout necessary to not blur the iframe too quickly
    setTimeout(() => activeElement.blur(), 0);
    return;
  }

  doBlurStuff();
};

window.addEventListener('blur', handleLeave);

因此,当window模糊时,我们正在检查用户是否单击了iframe。如果是这样,我们将使iframe模糊化(用户的动作已经发生),它将焦点返回到document.body。由于未知的原因(可能是发生的太快,或者我们没有明确地focus使用document.body),任何window focus处理程序都不会触发。而且由于我们return要早点出发,因此doBlurStuff也不会触发。

一个权衡:由于我们在关注焦点,因此存在可访问性和UX问题。用户将无法使用iframe的键盘事件,因为它将永远无法保持焦点。对于许多用途而言,这种折衷可能不值得。