【问题标题】:How to access onfocus event from iframe (cross-origin)?如何从 iframe(跨域)访问 onfocus 事件?
【发布时间】:2016-03-05 05:08:09
【问题描述】:

我有使用 onfocus 事件的 html 应用程序。切换浏览器选项卡时效果很好。

现在,当我在另一个 html 页面中将该应用程序作为 iframe 加载时,它不起作用,因为在切换选项卡时 iframe 没有聚焦。如何从iframe 访问onfocus 事件无需修改顶级代码

iframe 和加载 iframe 的页面不是同一来源。

if (!window.parent.frames.length) {
    window.onfocus = function () {
        // do smth
    };
} else {
    // ???
}

【问题讨论】:

  • 请发布最低代码以显示其设置方式。
  • 我看到 iframe 和父文档的来源不同。您是否控制两个文档/来源中的内容?
  • 这是最低限度的代码。我正在做一些基于事件(套接字)的动画。它们应该是实时动画,所以我需要一个队列。切换选项卡时,应该清理队列,如果应用程序不是iframe,它就可以工作。但是当它是iframe 时,我无法清理队列,因为onfocus 事件不会启动。 @Amber de Black 答案可能是我的解决方案。
  • @J.Kovacevic 试试我提供的答案,它使用postMessage 将父级onfocus 事件传递给<iframe>

标签: javascript iframe


【解决方案1】:

您可以使用 HTML5 Visibility API。它允许您检测用户何时离开并返回选项卡。

在我写这篇文章的那一刻——90% 的浏览器都支持这个功能: http://caniuse.com/#feat=pagevisibility

iframe 页面示例代码:

document.addEventListener('visibilitychange', function(){
    var time = new Date();

    if (document.hidden) {
            console.log(time + ' the user has left tab');
    } else {
            console.log(time + ' the user has returned to the tab');
    } 
})

【讨论】:

    【解决方案2】:

    如果您同时控制父页面和 iframe 页面的内容,则可以使用 postMessage 将父页面的 onfocus 事件传递到 iframe。

    这是一个例子:

    <iframe>内容:

    <!doctype html>
    <html>
        <head>
        <script>
            // Function to call when receiving a `postMessage`
            function listener(event){
                if (event.data === 'focus-event') {
                    document.querySelector("body").innerHTML += '<h2>Parent is in focus</h2>';
                }
            };
    
            // `postMessage` event listener
            window.addEventListener('message', listener, false);
        </script>
        </head>
        <body>
            <h1>Child</h1>
        </body>
    </html>;
    

    父内容:

    window.addEventListener('focus', function(event){
        iframe.postMessage('focus-event', '*');
    }, false);
    

    这将使父窗口每次收到focus 事件时都会将该消息发布到 iframe。

    这是JSBin example

    【讨论】:

    • 是的,这也是一种解决方案。我正在使用postMessage 将一些事件从iframe(我的应用程序)发送到父框架,这部分是可选的,它只是为父框架提供了一些额外的数据。我使用了@amber 解决方案,因为应用程序将像插件一样实现,有时我无法将父级的onfocus 事件传递给 iframe。
    猜你喜欢
    • 2013-03-05
    • 1970-01-01
    • 2014-03-16
    • 2012-04-05
    • 2018-12-15
    • 1970-01-01
    • 2021-09-06
    相关资源
    最近更新 更多