在同一浏览器中使用其他选项卡后,iFrame内容消失

时间:2016-06-29 15:45:34

标签: javascript jquery html iframe

有很多关于消失的iFrame内容的帖子,但我能找到的内容是关于立即消失,或随机消失的内容。

我的情况有点不同。

我在父div中有一个iframe

<div id="punt" contentid="123">
    <iframe id="content_frame" sandbox="allow-forms allow-popups allow-scripts allow-same-origin" src="" ></iframe>
</div>

iframe完全填充其父级,其本身几乎是视口的全尺寸。

iframe的内容是通过JS / JQuery设置的:

function loadURL(url){
    $('#content_frame').attr('src', url);
}

此外,eventListeners绑定到iframe

$("#content_frame").on("load", function () {
    if(isNewURL){
        bindAndFocus();
    }
});

,其中

function bindAndFocus(){
    $('#content_frame').bind({
        mouseenter: function(e) {
            overiFrame = $(this).parent().attr('contentid');
        },
        mouseleave: function(e) {
            overiFrame = -1;
        }
    });
}

清除内容后,听众将被解雇:

$('#content_frame').unbind('mouseenter mouseleave');

这一切都很棒。 URL加载正常,内容可滚动并且可以与在浏览器中直接查看一样进行交互。在确定iframe何时与之交互时,听众是一个黑客共同的尝试(来自另一个SO帖子) - 一点点击中和未命中,但不是手头的问题。

但是......

神秘的消失法案?

当您将网址加载到iframe,然后在其他标签中播放一段时间(在同一浏览器中)时,会出现此问题。 消失不是即时的 - 在几个标签之间快速切换然后返回无效。但是当你在不同的标签中花费一些时间(几分钟或更长时间),然后返回时,内容 部分消失

澄清......

如果内容足够长以在iframe(即大多数网页)内滚动,则只有可见部分消失。滚动将显示已加载页面的其余部分,但如果不重新加载内容,则消失的部分不会重新显示。

视觉有助于消除任何混淆:

iframe mess

在图像中,iframe是红色框。里面的任何东西都是可见的,外面的任何东西都是隐藏的。

从左到右:

使用其他标签之前

  1. 在iframe中加载的网址

  2. 加载的页面在iframe中正确滚动,所有内容都可以查看

  3. 使用其他标签后

    1. 网址仍在iframe中加载,但框架(可见)内容已消失

    2. 在iframe中滚动显示已加载页面的剩余内容,但如果没有重新加载iframe中的网址,则消失的内容不会返回

    3. 注意:

      此行为仅在Safari中测试,但任何主要浏览器问题都是一个问题。这可能是仅限Safari的修复程序,也可能是通用的iframe问题。

      iframe除了沙盒安全问题,魔法消失的行为是怎么回事?

      一个明显的hacky 修复是为用户提供一个刷新按钮来重新加载内容,但这远非理想。

      (从here获取树/路径图像)

3 个答案:

答案 0 :(得分:1)

也许这是一个重绘/重排问题。这只是一个微弱的猜测:(

a.style.display='none';
a.offsetHeight;
a.style.display='block';

found here

尽量做到尽可能准确。出于测试目的,您可以参考IFrame-body。

More (a lot) information

我不确定何时重写最好的。您可以在mouseenter-handler上测试修复程序。也许你可以通过监听window.onblur和window.onfocus来检测tab-switch。

答案 1 :(得分:1)

我很好奇是在所有浏览器中发生这种情况,还是仅仅是Safari。从事物的声音,它听起来像一个浏览器的错误,没有你做错了。也许一些RAM优化会使丢失的像素成为令人讨厌的副作用。

我希望有人能够提供更好的功能,但是每次用户返回选项卡时,可能需要一个让您启动并运行的解决方法。不是高性能或者非常优雅,而是用户体验。

以下代码可能有助于减少性能消耗。

var url = 'what.com';
var loadURL = function(url) {
  // replace with your function
  console.log(url);
}

function getHiddenProp() {
    var prefixes = ['webkit','moz','ms','o'];
    
    // if 'hidden' is natively supported just return it
    if ('hidden' in document) return 'hidden';
    
    // otherwise loop over all the known prefixes until we find one
    for (var i = 0; i < prefixes.length; i++){
        if ((prefixes[i] + 'Hidden') in document) 
            return prefixes[i] + 'Hidden';
    }

    // otherwise it's not supported
    return null;
}

var isHidden = (function() {
    // I'm using an IIFE here so that getHiddenProp is only run once, when this code inits, instead of ever time the tab changes.
    var prop = getHiddenProp();
    return function() {
        if (!prop) return false;
        return document[prop];
    }
})();

document.addEventListener('visibilitychange', function(){
    if(isHidden() === false) {
        // Wrapping your function in this event listener and this if statement ensures it only runs when the user navigates back to this tab.  There may even be a more performant way of doing this, so poke around if you decide to use this.
        loadURL(url);
    }
});

请注意,我从这个有用的条目中获得了“is tab visible”代码:http://www.html5rocks.com/en/tutorials/pagevisibility/intro/

希望这有帮助!祝你好运!

答案 2 :(得分:0)

您的计算机有多少内存? iframe可能已从内存中卸载,因为所有选项卡都可用内存较少,Safari认为iframe不重要。在这种情况下,你可以做的很少(其他升级你的计算机),虽然试图找出JQuery是否占用内存(它是一个巨大的库)并尝试缩小你的代码(使用删除空格的程序等。)