本文介绍了专注于跨源iframe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a web app with an embedded video within an iframe, typically from a cross-origin source (e.g. YouTube). I currently track focus on window for logging purposes. However, since iframes are not children of window, when the user clicks into the iframe, window blurs, stopping my logs though the user is still viewing the page. How can I track focus to this cross-origin iframe?

推荐答案

tl; dr-您无法跟踪iframe的焦点,至少不能直接跟踪.但是还有其他有用的信息来源.

tl;dr - you can't track focus on the iframe, at least not directly. But there are other sources of information that can be useful enough.

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

Since the iframe is cross-origin, that immediately rules out accessing its focus state directly, attaching any event handlers, or posting any messages. However, you can use document.body.activeElement to see if the user clicked on the iframe as opposed to another tab/window. With that knowledge, this hack is possible:

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也不会触发.

So when window blurs, we're checking to see if the user clicked on the iframe. If they did, we're going to blur the iframe (the user's action will have already occurred), which returns focus to document.body. For unknown reasons (probably either that it happens too quickly, or that we're not explicitly focusing document.body), any window focus handlers don't fire. And since we're returning early, doBlurStuff also doesn't fire.

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

One tradeoff: since we're focus-jacking, this has accessibility and UX concerns. The user will not be able to use keyboard events for the iframe, since it will never be able to hold focus. This tradeoff may not be worth it for many usages.

这篇关于专注于跨源iframe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:32