window.requestAnimationFrame静默无法调用回调,但在跨域iframe内调用时会生成有效的requestID

Sea*_*son 2 javascript iframe cross-domain google-chrome-extension

我正在开发Google Chrome扩展程序.在这种环境中,我可以在请求适当的权限后将JavaScript注入第三方网站.因此,我将代码注入引用跨域资源的iframe,但不受与"普通"环境中预期相同的跨源安全策略的约束.

我在这个iframe中执行的代码是:

var requestId = window.requestAnimationFrame(function(){
    console.log("Success");
});
console.log("Request Id:", requestId);
Run Code Online (Sandbox Code Playgroud)

执行此代码后,我的输出如下:

请求ID:1

requestAnimationFrame的回调永远不会被执行.requestAnimationFrame已定义.如果我使用非优化调用(如setInterval),则回调可以正常工作.

回调在iframe外部正确执行,在iframe内部失败时,我的控制台中没有显示安全错误.这仅适用于最新版本的Google Chrome - 请不要担心requestAnimationFrame的其他实现.

我可以采取任何步骤来调试此问题吗?window.requestAnimationFrame落后于本机代码,我的requestId是有效的...所以我有点不知所措.

编辑:

以下是将此问题作为小型Google Chrome扩展程序重现的完整源代码:https://gist.github.com/MeoMix/37b4dbdbb3bd48f3c9e2

这是上面源代码的可下载zip:https://mega.co.nz/#!2BFA1agY!JSZC1BFBza3rU4LnqlZqcR9neZQRJn0yh1U6tu2GWo4

Rob*_*b W 6

您的问题与iframe无关,但与背景页面不可见.

将背景页面视为非焦点选项卡.如果requestAnimationFrame在非活动选项卡中使用,则在再次聚焦选项卡之前不会调用回调,如下一个示例所示.由于后台页面永远不会"聚焦",因此永远不会调用RAF回调.

将以下代码粘贴到控制台中,然后移动到其他选项卡.等待几秒钟再重新激活标签.您将看到控制台中记录的时间戳非常接近.这表明仅当选项卡再次聚焦时才会调用RAF的回调.

setTimeout(function() {
    console.time(1);
    console.time(2)
    requestAnimationFrame(function() {
        console.timeEnd(1)
    });
}, 2000)
window.onfocus = function() {
    console.timeEnd(2);
};
Run Code Online (Sandbox Code Playgroud)

问题的"解决方案"是使用旧的setTimeout代替:

setTimeout(function() {
    console.log('Success');
}, 25); // 40 Hz.
Run Code Online (Sandbox Code Playgroud)