I’m attempting to use a jQuery script I’ve found on
http://swip.codylindley.com/DOMWindowDemo.html
on my website to create a lightbox/domwindow popup when a visitor clicks a link.
Unfortunately, it appears the script isn’t releasing memory when the user closes the dom window. If the user opens and closes the window several times, it causes the page to slow down dramatically and crash the user’s browser.
Here is the jQuery script from the above website:
(function($){
//closeDOMWindow
$.fn.closeDOMWindow = function(settings){
if(!settings){settings={};}
var run = function(passingThis){
if(settings.anchoredClassName){
var $anchorClassName = $('.'+settings.anchoredClassName);
$anchorClassName.fadeOut('fast',function(){
if($.fn.draggable){
$anchorClassName.draggable('destory').trigger("unload").remove();
}else{
$anchorClassName.trigger("unload").remove();
}
});
if(settings.functionCallOnClose) {
settings.functionCallAfterClose();
}
}else{
var $DOMWindowOverlay = $('#DOMWindowOverlay');
var $DOMWindow = $('#DOMWindow');
$DOMWindowOverlay.fadeOut('fast',function(){
$DOMWindowOverlay.trigger('unload').unbind().remove();
});
$DOMWindow.fadeOut('fast',function(){
if($.fn.draggable){
$DOMWindow.draggable("destroy").trigger("unload").remove();
}else{
$DOMWindow.trigger("unload").remove();
}
});
$(window).unbind('scroll.DOMWindow');
$(window).unbind('resize.DOMWindow');
if($.fn.openDOMWindow.isIE6){$('#DOMWindowIE6FixIframe').remove();}
if(settings.functionCallOnClose){settings.functionCallAfterClose();}
}
};
if(settings.eventType){//if used with $().
return this.each(function(index){
$(this).bind(settings.eventType, function(){
run(this);
return false;
});
});
}else{//else called as $.function
run();
}
};
//allow for public call, pass settings
$.closeDOMWindow = function(s){$.fn.closeDOMWindow(s);};
//openDOMWindow
$.fn.openDOMWindow = function(instanceSettings){
var shortcut = $.fn.openDOMWindow;
//default settings combined with callerSettings////////////////////////////////////////////////////////////////////////
shortcut.defaultsSettings = {
anchoredClassName:'',
anchoredSelector:'',
borderColor:'#ccc',
borderSize:'4',
draggable:0,
eventType:null, //click, blur, change, dblclick, error, focus, load, mousedown, mouseout, mouseup etc...
fixedWindowY:100,
functionCallOnOpen:null,
functionCallOnClose:null,
height:500,
loader:0,
loaderHeight:0,
loaderImagePath:'',
loaderWidth:0,
modal:0,
overlay:1,
overlayColor:'#000',
overlayOpacity:'85',
positionLeft:0,
positionTop:0,
positionType:'centered', // centered, anchored, absolute, fixed
width:500,
windowBGColor:'#fff',
windowBGImage:null, // http path
windowHTTPType:'get',
windowPadding:10,
windowSource:'inline', //inline, ajax, iframe
windowSourceID:'',
windowSourceURL:'',
windowSourceAttrURL:'href'
};
var settings = $.extend({}, $.fn.openDOMWindow.defaultsSettings , instanceSettings || {});
//Public functions
shortcut.viewPortHeight = function(){ return self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;};
shortcut.viewPortWidth = function(){ return self.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;};
shortcut.scrollOffsetHeight = function(){ return self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;};
shortcut.scrollOffsetWidth = function(){ return self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;};
shortcut.isIE6 = typeof document.body.style.maxHeight === "undefined";
//Private Functions/////////////////////////////////////////////////////////////////////////////////////////////////////////
var sizeOverlay = function(){
var $DOMWindowOverlay = $('#DOMWindowOverlay');
if(shortcut.isIE6){//if IE 6
var overlayViewportHeight = document.documentElement.offsetHeight + document.documentElement.scrollTop - 4;
var overlayViewportWidth = document.documentElement.offsetWidth - 21;
$DOMWindowOverlay.css({'height':overlayViewportHeight +'px','width':overlayViewportWidth+'px'});
}else{//else Firefox, safari, opera, IE 7+
$DOMWindowOverlay.css({'height':'100%','width':'100%','position':'fixed'});
}
};
var sizeIE6Iframe = function(){
var overlayViewportHeight = document.documentElement.offsetHeight + document.documentElement.scrollTop - 4;
var overlayViewportWidth = document.documentElement.offsetWidth - 21;
$('#DOMWindowIE6FixIframe').css({'height':overlayViewportHeight +'px','width':overlayViewportWidth+'px'});
};
var centerDOMWindow = function() {
var $DOMWindow = $('#DOMWindow');
if(settings.height + 50 > shortcut.viewPortHeight()){//added 50 to be safe
$DOMWindow.css('left',Math.round(shortcut.viewPortWidth()/2) + shortcut.scrollOffsetWidth() - Math.round(($DOMWindow.outerWidth())/2));
}else{
$DOMWindow.css('left',Math.round(shortcut.viewPortWidth()/2) + shortcut.scrollOffsetWidth() - Math.round(($DOMWindow.outerWidth())/2));
$DOMWindow.css('top',Math.round(shortcut.viewPortHeight()/2) + shortcut.scrollOffsetHeight() - Math.round(($DOMWindow.outerHeight())/2));
}
};
var centerLoader = function() {
var $DOMWindowLoader = $('#DOMWindowLoader');
if(shortcut.isIE6){//if IE 6
$DOMWindowLoader.css({'left':Math.round(shortcut.viewPortWidth()/2) + shortcut.scrollOffsetWidth() - Math.round(($DOMWindowLoader.innerWidth())/2),'position':'absolute'});
$DOMWindowLoader.css({'top':Math.round(shortcut.viewPortHeight()/2) + shortcut.scrollOffsetHeight() - Math.round(($DOMWindowLoader.innerHeight())/2),'position':'absolute'});
}else{
$DOMWindowLoader.css({'left':'50%','top':'50%','position':'fixed'});
}
};
var fixedDOMWindow = function(){
var $DOMWindow = $('#DOMWindow');
$DOMWindow.css('left', settings.positionLeft + shortcut.scrollOffsetWidth());
$DOMWindow.css('top', + settings.positionTop + shortcut.scrollOffsetHeight());
};
var showDOMWindow = function(instance){
if(arguments[0]){
$('.'+instance+' #DOMWindowLoader').remove();
$('.'+instance+' #DOMWindowContent').fadeIn('fast',function(){if(settings.functionCallOnOpen){settings.functionCallOnOpen();}});
$('.'+instance+ '.closeDOMWindow').click(function(){
$.closeDOMWindow();
return false;
});
}else{
$('#DOMWindowLoader').remove();
$('#DOMWindow').fadeIn('fast',function(){if(settings.functionCallOnOpen){settings.functionCallOnOpen();}});
$('#DOMWindow .closeDOMWindow').click(function(){
$.closeDOMWindow();
return false;
});
}
};
var urlQueryToObject = function(s){
var query = {};
s.replace(/b([^&=]*)=([^&=]*)b/g, function (m, a, d) {
if (typeof query[a] != 'undefined') {
query[a] += ',' + d;
} else {
query[a] = d;
}
});
return query;
};
//Run Routine ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
var run = function(passingThis){
//get values from element clicked, or assume its passed as an option
settings.windowSourceID = $(passingThis).attr('href') || settings.windowSourceID;
settings.windowSourceURL = $(passingThis).attr(settings.windowSourceAttrURL) || settings.windowSourceURL;
settings.windowBGImage = settings.windowBGImage ? 'background-image:url('+settings.windowBGImage+')' : '';
var urlOnly, urlQueryObject;
if(settings.positionType == 'anchored'){//anchored DOM window
var anchoredPositions = $(settings.anchoredSelector).position();
var anchoredPositionX = anchoredPositions.left + settings.positionLeft;
var anchoredPositionY = anchoredPositions.top + settings.positionTop;
$('body').append('<div class="'+settings.anchoredClassName+'" style="'+settings.windowBGImage+';background-repeat:no-repeat;padding:'+settings.windowPadding+'px;overflow:auto;position:absolute;top:'+anchoredPositionY+'px;left:'+anchoredPositionX+'px;height:'+settings.height+'px;width:'+settings.width+'px;background-color:'+settings.windowBGColor+';border:'+settings.borderSize+'px solid '+settings.borderColor+';z-index:10001"><div id="DOMWindowContent" style="display:none"></div></div>');
//loader
if(settings.loader && settings.loaderImagePath !== ''){
$('.'+settings.anchoredClassName).append('<div id="DOMWindowLoader" style="width:'+settings.loaderWidth+'px;height:'+settings.loaderHeight+'px;"><img src="'+settings.loaderImagePath+'" /></div>');
}
if($.fn.draggable){
if(settings.draggable){$('.' + settings.anchoredClassName).draggable({cursor:'move'});}
}
switch(settings.windowSource){
case 'inline'://////////////////////////////// inline //////////////////////////////////////////
$('.' + settings.anchoredClassName+" #DOMWindowContent").append($(settings.windowSourceID).children());
$('.' + settings.anchoredClassName).unload(function(){// move elements back when you're finished
$('.' + settings.windowSourceID).append( $('.' + settings.anchoredClassName+" #DOMWindowContent").children());
});
showDOMWindow(settings.anchoredClassName);
break;
case 'iframe'://////////////////////////////// iframe //////////////////////////////////////////
$('.' + settings.anchoredClassName+" #DOMWindowContent").append('<iframe frameborder="0" hspace="0" wspace="0" src="'+settings.windowSourceURL+'" name="DOMWindowIframe'+Math.round(Math.random()*1000)+'" style="width:100%;height:100%;border:none;background-color:#fff;" class="'+settings.anchoredClassName+'Iframe" ></iframe>');
$('.'+settings.anchoredClassName+'Iframe').load(showDOMWindow(settings.anchoredClassName));
break;
case 'ajax'://////////////////////////////// ajax //////////////////////////////////////////
if(settings.windowHTTPType == 'post'){
if(settings.windowSourceURL.indexOf("?") !== -1){//has a query string
urlOnly = settings.windowSourceURL.substr(0, settings.windowSourceURL.indexOf("?"));
urlQueryObject = urlQueryToObject(settings.windowSourceURL);
}else{
urlOnly = settings.windowSourceURL;
urlQueryObject = {};
}
$('.' + settings.anchoredClassName+" #DOMWindowContent").load(urlOnly,urlQueryObject,function(){
showDOMWindow(settings.anchoredClassName);
});
}else{
if(settings.windowSourceURL.indexOf("?") == -1){ //no query string, so add one
settings.windowSourceURL += '?';
}
$('.' + settings.anchoredClassName+" #DOMWindowContent").load(
settings.windowSourceURL + '&random=' + (new Date().getTime()),function(){
showDOMWindow(settings.anchoredClassName);
});
}
break;
}
}else{//centered, fixed, absolute DOM window
//overlay & modal
if(settings.overlay){
$('body').append('<div id="DOMWindowOverlay" style="z-index:10000;display:none;position:absolute;top:0;left:0;background-color:'+settings.overlayColor+';filter:alpha(opacity='+settings.overlayOpacity+');-moz-opacity: 0.'+settings.overlayOpacity+';opacity: 0.'+settings.overlayOpacity+';"></div>');
if(shortcut.isIE6){//if IE 6
$('body').append('<iframe id="DOMWindowIE6FixIframe" src="blank.html" style="width:100%;height:100%;z-index:9999;position:absolute;top:0;left:0;filter:alpha(opacity=0);"></iframe>');
sizeIE6Iframe();
}
sizeOverlay();
var $DOMWindowOverlay = $('#DOMWindowOverlay');
$DOMWindowOverlay.fadeIn('fast');
if(!settings.modal){$DOMWindowOverlay.click(function(){$.closeDOMWindow();});}
}
//loader
if(settings.loader && settings.loaderImagePath !== ''){
$('body').append('<div id="DOMWindowLoader" style="z-index:10002;width:'+settings.loaderWidth+'px;height:'+settings.loaderHeight+'px;"><img src="'+settings.loaderImagePath+'" /></div>');
centerLoader();
}
//add DOMwindow
$('body').append('<div id="DOMWindow" style="background-repeat:no-repeat;'+settings.windowBGImage+';overflow:auto;padding:'+settings.windowPadding+'px;display:none;height:'+settings.height+'px;width:'+settings.width+'px;background-color:'+settings.windowBGColor+';border:'+settings.borderSize+'px solid '+settings.borderColor+'; position:absolute;z-index:10001"></div>');
var $DOMWindow = $('#DOMWindow');
//centered, absolute, or fixed
switch(settings.positionType){
case 'centered':
centerDOMWindow();
if(settings.height + 50 > shortcut.viewPortHeight()){//added 50 to be safe
$DOMWindow.css('top', (settings.fixedWindowY + shortcut.scrollOffsetHeight()) + 'px');
}
break;
case 'absolute':
$DOMWindow.css({'top':(settings.positionTop+shortcut.scrollOffsetHeight())+'px','left':(settings.positionLeft+shortcut.scrollOffsetWidth())+'px'});
if($.fn.draggable){
if(settings.draggable){$DOMWindow.draggable({cursor:'move'});}
}
break;
case 'fixed':
fixedDOMWindow();
break;
case 'anchoredSingleWindow':
var anchoredPositions = $(settings.anchoredSelector).position();
var anchoredPositionX = anchoredPositions.left + settings.positionLeft;
var anchoredPositionY = anchoredPositions.top + settings.positionTop;
$DOMWindow.css({'top':anchoredPositionY + 'px','left':anchoredPositionX+'px'});
break;
}
$(window).bind('scroll.DOMWindow',function(){
if(settings.overlay){sizeOverlay();}
if(shortcut.isIE6){sizeIE6Iframe();}
if(settings.positionType == 'centered'){centerDOMWindow();}
if(settings.positionType == 'fixed'){fixedDOMWindow();}
});
$(window).bind('resize.DOMWindow',function(){
if(shortcut.isIE6){sizeIE6Iframe();}
if(settings.overlay){sizeOverlay();}
if(settings.positionType == 'centered'){centerDOMWindow();}
});
switch(settings.windowSource){
case 'inline'://////////////////////////////// inline //////////////////////////////////////////
$DOMWindow.append($(settings.windowSourceID).children());
$DOMWindow.unload(function(){// move elements back when you're finished
$(settings.windowSourceID).append($DOMWindow.children());
});
showDOMWindow();
break;
case 'iframe'://////////////////////////////// iframe //////////////////////////////////////////
$DOMWindow.append('<iframe frameborder="0" hspace="0" wspace="0" src="'+settings.windowSourceURL+'" name="DOMWindowIframe'+Math.round(Math.random()*1000)+'" style="width:100%;height:100%;border:none;background-color:#fff;" id="DOMWindowIframe" ></iframe>');
$('#DOMWindowIframe').load(showDOMWindow());
break;
case 'ajax'://////////////////////////////// ajax //////////////////////////////////////////
if(settings.windowHTTPType == 'post'){
if(settings.windowSourceURL.indexOf("?") !== -1){//has a query string
urlOnly = settings.windowSourceURL.substr(0, settings.windowSourceURL.indexOf("?"));
urlQueryObject = urlQueryToObject(settings.windowSourceURL);
}else{
urlOnly = settings.windowSourceURL;
urlQueryObject = {};
}
$DOMWindow.load(urlOnly,urlQueryObject,function(){
showDOMWindow();
});
}else{
if(settings.windowSourceURL.indexOf("?") == -1){ //no query string, so add one
settings.windowSourceURL += '?';
}
$DOMWindow.load(
settings.windowSourceURL + '&random=' + (new Date().getTime()),function(){
showDOMWindow();
});
}
break;
}
}//end if anchored, or absolute, fixed, centered
};//end run()
if(settings.eventType){//if used with $().
return this.each(function(index){
$(this).bind(settings.eventType,function(){
run(this);
return false;
});
});
}else{//else called as $.function
run();
}
};//end function openDOMWindow
//allow for public call, pass settings
$.openDOMWindow = function(s){$.fn.openDOMWindow(s);};
})(jQuery);
And here is the hyperlink tag from my HTML that opens up the light box.
<a href="/php/ajax/edit_map_pin.htm?mAddressBox0=FALSE&mPin_ID=foo" class="AjaxDOMWindow">Change Icon</a>
Here is a screenshot from siege detailing the memory step increase every time the user opens and closes the DOM window from that link. Any help is greatly appreciated. Thanks!

The problem is, that remove() removes nodes from the document-tree, but they still are available(for example you can use them again and put them back to the document).
In MSIE you can set the outerHTML-property of nodes to an empty string to really delete them, in other browsers I’m not sure how. You may have a look at this: http://www.josh-davis.org/node/7 .
The author uses there the delete-statement, but I’m not sure if it really deletes the nodes.