【问题标题】:iframe based IE6 javascript memory leak?基于 iframe 的 IE6 javascript 内存泄漏?
【发布时间】:2010-12-24 08:53:14
【问题描述】:

我正在使用 iframe 通过带有正在更新的 jquery 的菜单加载内容 iframe 的“src”属性,然后加载到所需的页面中。每个 页面有自己的 javascript 包含和大量内容。

代码如下:-

$(document).ready(function() {
    loadPage('main.php');
});

function loadPage(url) {
    $('#applicationFrame').attr('src', url);
}

并且索引页面上的 iframe 如下所示:-

<iframe id="applicationFrame" application="yes" trusted="yes" frameborder="0" />

(旁注:我意识到这里的 iframe 采用非标准属性,但是 这是在其中一个 Microsoft 中运行的内部 Intranet 应用程序 在 HTA 中它们确实有意义。)

无论如何,菜单项只是在调用 javascript:loadPage('whatever.php') 为了加载任何需要的内容。

我面临的问题是,在每个后续页面上单击菜单 帧正在泄漏内存,直到最终整个应用程序慢下来。 sIEve 报告如下:-

leaks http://img37.imageshack.us/img37/3997/leaks.png

每次点击 (21 -> 44 -> 65) 等时,此处的泄漏列都会上升。

检查泄漏检查器显示:

inspector http://img527.imageshack.us/img527/4430/inspector.png

在我看来,这只是泄露的整个 iframe 内容。

有没有办法避免这种情况?我错过了什么吗?我发现了一个类似的问题 here dojo 框架有,但尝试建议的解决方案没有 似乎工作。我还尝试了很多其他粘贴的东西 here 但没有解决。

这似乎(令人惊讶)只影响 IE6,它确实是唯一的目标 应用程序的受众。

【问题讨论】:

    标签: javascript jquery iframe memory-leaks internet-explorer-6


    【解决方案1】:

    手头有一点时间,尝试了一个 jQuery less 变体。根据 SIEve,似乎不再泄漏。

    function pos(obj) {
        var curleft = 0;
        var curtop = 0;
        if (obj.offsetParent) {
            do {
                curleft += obj.offsetLeft;
                curtop += obj.offsetTop;
            } while (obj = obj.offsetParent);
        }
        obj = null;
        return {left:curleft, top:curtop};
    }
    
    function loadPage(url) {
        var y = document.getElementById('container');
        var x = document.getElementById('applicationFrame');
        var p = pos(y);
        if (x.src) {
            var tmp = y.cloneNode(false);
            var tmpIF = x.cloneNode(false);
            tmpIF.src = url;
            tmp.appendChild(tmpIF);
            tmp.style.position = 'absolute';
            tmp.style.visibility = 'hidden';
            tmp.style["z-index"] = 20;
            tmp.style.top = p.top;
            tmp.style.left = p.left;
            y.id = "delete";
            x.id = "deleteApplicationFrame";
            document.getElementsByTagName("body")[0].appendChild(tmp);
            tmpIF = null; tmp = null;
        }
        setTimeout("document.getElementById('applicationFrame').style.visibility = 'visible'; var i = document.getElementById('deleteApplicationFrame'); i = i.contentDocument || i.contentWindow.document; i.documentElement.parentNode.removeChild(i.documentElement); i=null; i=document.getElementById('delete'); i.parentNode.removeChild(i); i=null;", 500);
        y = null; x = null; p = null;
    }
    
    <div id="container">
        <iframe id="applicationFrame" application="yes" trusted="yes" frameborder="0" src="main.php"/>
    </div>
    

    如果不了解整个应用程序,很难判断可能发生的情况。特别是 IE6 是一个内存泄漏的 b..ch。

    一些阅读链接

    Understanding and Solving Internet Explorer Leak Patterns

    Fixing Leaks

    Memory Leakage in Internet Explorer - revisited


    只是一个想法,AFAIK 将src 设置为不同值时的行为并没有真正在 W3C HTML DOM 规范中指定,还是它(链接任何人?)?

    我建议您在 iframe 上设置初始 src="main.php" 值,而不是使用 loadPage('main.php'); 并为 iframe 设置名称。

    理想情况下,您的菜单项是 &lt;a&gt; 标签,然后您可以使用 &lt;a href="notmain.php" target="nameOfYourIFrame"&gt;FooBar&lt;/a&gt; 而不是基于 javascript 的解决方案进行测试

    【讨论】:

    • 您好,感谢您的回复。我意识到尝试解决这是一个非常可怕的问题。哦,感谢我以前看过的链接。至于菜单项,我尝试了使用锚标签的建议,这让我充满希望(我之前只是使用 onclick 事件),但不幸的是它似乎以同样的方式泄漏(但没那么糟糕)。将 src="main.php" 设置为默认值可以减少第一次单击时的泄漏次数,在屏幕截图中已更改为“1”而不是“21”,这有帮助。问题仍然存在,但您单击的部分越多。准备重写(!)
    • 哇,这很完美。非常感谢这一点,它让我在使用 IE6 时少了一点头发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 2012-07-27
    相关资源
    最近更新 更多