I have been tracking down a memory leak in my web app which dynamically removes and adds anchors which have cluetip tooltips attached and I think that I may have narrowed down the problem to the main closure in cluetip which attaches the cluetip to the node (line 32: var link = this, $this = $(this);).
I have been running the following script in SIEV with a modified version of jquery 1.3.2 with the following fix which allows the cluetip elements to be removed. However, the anchor nodes become orphaned as there is still 1 reference to them after the cluetip nodes are removed?
If I change line 32 of the cluetip source to the following for testing purposes: var link = $('br'), $this = $('br');
The anchors are freed but the 'br' nodes start building up.
Therefore, I was wondering if anyone knows how I can work around this problem? or if I am simply not releasing the resources correctly?
Attached Scripts and Source:
jQuery modification. After line 1247 insert the following before the closing curly brace (http://markmail.org/message/cfi4bvfjc3m6ww6k#query:jquery%20memory%20leak%20in%20remove%20and%20empty+page:1+mid:tapc7zt3cwl6rw4f+state:results):
this.outerHTML = "";
Example Script:
<html>
<head>
<link rel="stylesheet" type="text/css" href="jquery.cluetip.css"/>
<script type="text/javascript" src="jquery-1.3.2.js"></script>
<script type="text/javascript" src="jquery.cluetip.js"></script>
<script type="text/javascript">
$(document).ready(function() {
setInterval(resetCluetip, 1000);
});
function resetCluetip() {
$('a').each(function() {
$(this).cluetip('destroy');
$(this).unbind().remove();
});
$('#cluetip*').unbind().empty();
$('body').html('<a href="#" class="contextMenu" title="title|body">anchor one</a><br>');
$('a').each(function() {
$(this).cluetip({splitTitle: '|'});
});
}
</script>
</head>
<body>
</body>
</html>
So here are a few comments:
ajaxCache: false
if you are getting the updates via ajax?.remove()
on an object should remove it from the DOM and also unbind any references, so you shouldn't need to use.unbind().remove();
or.unbind().empty();
$('#cluetip*')
a better way to do this is to use a selector attribute filter like this$('div[id*="cluetip"]')