jQuery DOMWindow脚本不释放内存 [英] jQuery DOMWindow script doesn't release memory

查看:126
本文介绍了jQuery DOMWindow脚本不释放内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用我在
上找到的jQuery脚本 http:/ /swip.codylindley.com/DOMWindowDemo.html
在我的网站上创建一个灯箱/ domwindow弹出窗口当访问者点击一个链接。

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.

不幸的是,当用户关闭dom窗口时,脚本不会释放内存。如果用户多次打开和关闭窗口,它会导致页面显着减慢,并使用户的浏览器崩溃。

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.

以下是上述网站的jQuery脚本:

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);

这里是打开灯箱的HTML中的超链接标签。

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>

这是一个围攻的屏幕截图,详细说明了每次用户打开并关闭DOM窗口的内存步长增加从那个链接。任何帮助是极大的赞赏。谢谢!

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!

推荐答案

问题是,remove()从文档树中删除节点,但仍然可用(例如,您可以再次使用它们并将其放回到文档中)。

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).

在MSIE中,您可以将节点的outerHTML属性设置为空字符串,以真正删除它们,在其他浏览器中,我不知道如何。你可以看看这个: http://www.josh-davis.org/node/7

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 .

作者在那里使用delete-statement,但我不知道是否真的删除节点。

The author uses there the delete-statement, but I'm not sure if it really deletes the nodes.

这篇关于jQuery DOMWindow脚本不释放内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆