问题
I'm loading in content using an iframe via a menu with jquery which is updating the 'src' attribute of the iframe to then load in the desired page. Each of the pages have their own javascript includes and heavy content.
The code is as follows:-
$(document).ready(function() {
loadPage('main.php');
});
function loadPage(url) {
$('#applicationFrame').attr('src', url);
}
And the iframe on the index page looks as follows:-
<iframe id="applicationFrame" application="yes" trusted="yes" frameborder="0" />
(Side note: I realise that the iframe here is taking nonstandard attributes, but this is an internal intranet application running in one of these Microsoft HTA's in which they do mean something.)
Anyway, the menu items are just calling javascript:loadPage('whatever.php') in order to load in whatever content is needed.
The problem I'm facing is that on each subsequent page click of the menu the frames are leaking memory until eventually the entire app slows to a crawl. sIEve reports the following:-
leaks http://img37.imageshack.us/img37/3997/leaks.png
The leaks column is ascending here with every click (21 -> 44 -> 65) etc.
Examining the leaks inspector shows:
inspector http://img527.imageshack.us/img527/4430/inspector.png
Which looks to me like it is just the entire iframed content which has leaked.
Is there anyway to avoid this? Am I missing something? I've found a similar issue here that the dojo framework has had, but trying the suggested solutions hasn't seemed to work. I've also tried a bunch of other things as pasted here but to no resolve.
This only seems to (surprise) affect IE6 which is really the only target audience of the application.
回答1:
Had a little time at hand and tried a jQuery less variant. Doesn't seem to leak anymore according to 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>
Very hard to tell what could possibly be going on without knowing the whole application. Especially IE6 is a b..ch with memory leaking.
A few reading links
Understanding and Solving Internet Explorer Leak Patterns
Fixing Leaks
Memory Leakage in Internet Explorer - revisited
Just a thought, AFAIK the behavior when setting src
to a different value isn't really specified in the W3C HTML DOM specification or is it (link anyone?)?
I suggest that you set an initial src="main.php"
value on the iframe instead of using loadPage('main.php');
and set a name for the iframe.
Ideally your menu items are <a>
tags then you could test using <a href="notmain.php" target="nameOfYourIFrame">FooBar</a>
instead of the javascript based solution
来源:https://stackoverflow.com/questions/1865958/iframe-based-ie6-javascript-memory-leak