jQuery UI对话框内存泄漏

jQuery UI对话框内存泄漏,jquery,internet-explorer,jquery-ui,memory-leaks,closures,Jquery,Internet Explorer,Jquery Ui,Memory Leaks,Closures,我正在使用IE7和一些jQuery对话框,每次打开一个对话框,我都会遇到大约6meg的泄漏。我假设这与闭包有关,但到目前为止,我为移除它们所做的一切都没有帮助。在这一点上,我想我已经处理了所有的闭包,除了我传入的回调函数,但是即使在对话框关闭和移除之后,它仍然泄漏了6兆。相关的源代码是: function DialogDestroyAndRemove(event) { $(event.target).dialog("destroy").remove(); } function Call

我正在使用IE7和一些jQuery对话框,每次打开一个对话框,我都会遇到大约6meg的泄漏。我假设这与闭包有关,但到目前为止,我为移除它们所做的一切都没有帮助。在这一点上,我想我已经处理了所有的闭包,除了我传入的回调函数,但是即使在对话框关闭和移除之后,它仍然泄漏了6兆。相关的源代码是:

function DialogDestroyAndRemove(event) {
    $(event.target).dialog("destroy").remove();
}

function CallbackAndCloseDialog(event) {
    if (event.data.callback != undefined) {
        event.data.callback(event.data.callbackResponse);
    }
    $("#" + event.data.dialogId).unbind('dialogbeforeclose').dialog('close');
}

// alert dialog modal with ok button
function AlertDialog(dialogTitle, dialogText, callbackFunction) {
    // dynamically generate and add a div so we can create the pop-up
    $('body').append("<div id=\"alertDialog\" style=\"display:none;\" title=\"" + dialogTitle + "\">" + dialogText + "</div>");

    // define/configure the modal pop-up
    $("#alertDialog").dialog({
        draggable: false,
        resizable: false,
        modal: true,
        autoOpen: true,
        open: function() {
            $("#alertDialog").parents('.ui-dialog-buttonpane button:eq(0)')
            .focus() //focus so the button is highlighted by default
            .bind('click', {
                callback: callbackFunction,
                callbackResponse: 'OK',
                dialogId: 'alertDialog'
            }, CallbackAndCloseDialog);
        },
        overlay: { backgroundColor: '#000', opacity: 0.5 },
        buttons: { 'OK': function() { } }
    }).bind('dialogbeforeclose', function(event, ui) {
        // Close (X) button was clicked; NOT the OK button
        if (callbackFunction != undefined) {
            callbackFunction('cancel');
        }
        callbackFunction = null;
    }).bind('dialogclose', DialogDestroyAndRemove);
}
函数对话框删除和删除(事件){
$(event.target).dialog(“destroy”).remove();
}
函数CallbackAndCloseDialog(事件){
if(event.data.callback!=未定义){
event.data.callback(event.data.callbackResponse);
}
$(“#”+event.data.dialogId).unbind('dialogbeforeclose').dialog('close');
}
//带有“确定”按钮的警报对话框模式
函数AlertDialog(dialogTitle、dialogText、callbackFunction){
//动态生成并添加一个div,以便创建弹出窗口
$('body')。追加(“+dialogText+”);
//定义/配置模式弹出窗口
$(“#警报对话框”)。对话框({
可拖动:错误,
可调整大小:false,
莫代尔:是的,
自动打开:对,
打开:函数(){
$(“#alertDialog”).parents(“.ui对话框按钮平面按钮:eq(0)”)
.focus()//聚焦,因此默认情况下按钮高亮显示
.bind('单击'{
callback:callbackFunction,
callbackResponse:'确定',
dialogId:'alertDialog'
},Callback和CloseDialog);
},
覆盖:{backgroundColor:'#000',不透明度:0.5},
按钮:{'OK':函数(){}
}).bind('dialogbeforeclose',函数(事件,用户界面){
//单击了关闭(X)按钮;而不是确定按钮
if(callbackFunction!=未定义){
callbackFunction('cancel');
}
callbackFunction=null;
}).bind('dialogclose',DialogDestroyAndRemove);
}
我在上面做了一件事,我不确定是否需要它,那就是在定义OK按钮时(因此在引用回调时有一个闭包)使用.bind在对话框打开后定义它,而不是为OK按钮定义回调。我希望能够将回调作为数据的一部分传递给click事件可能有助于消除闭包


你知道我还能做些什么来消除这个漏洞吗?

它实际上是由jQuery UI框架在显示模式时处理背景灰显的方式造成的。如果删除modal=true和overlay属性,内存泄漏将下降到~100k

为了解决这个问题,我必须在没有模式选项的情况下创建对话框,然后自己在页面上添加一个div(固定位置顶部、左侧、底部、右侧均为0,交替使用灰色像素,然后是透明像素背景),并在对话框下方使用zindex显示和隐藏该对话框


虽然这并不理想(默认的模式覆盖很好,看起来很平滑),但总比每次弹出对话框时泄漏那么多内存要好。

希望这有所帮助,我为这个问题创建了一个扩展,在jQuery UI对话框中使用jQuery工具(flowplayer)在modal=true时暴露插件

我会包括folhttp://jsfiddle.net/yZ56q/lowing 在一个单独的.js文件中编写代码,并确保包含jQuery工具expose plugin previor,来自此站点


这与IE如何处理PNG透明度有关,这是非常可怕的。如果你用一个简单的彩色IE滤镜代替图像,你可以在不影响记忆的情况下获得一些效果。在jQuery.UI.css中,更改
.UI小部件覆盖
类并删除
url中的所有内容(
背景:
声明中前进),这将导致一个单色半透明覆盖。这似乎与IE处理透明度的一般方式有关。我删除了背景的url方面(只留下纯色)它仍然这样做。直到我移除不透明过滤器,它才消失。实际上,从我的对话框中移除模态:true将IE 8的内存使用减少了一半(从150 MB到70 MB)。
(function($) {
    var _init = $.ui.dialog.prototype._init;
    $.ui.dialog.prototype._init = function() {
        var self = this;
        _init.apply(this, arguments);

        // Remove the default modal behavior and exhibit the new one
        if (self.options.modal) {
            self.options.modal = false;
            self.options.isModal = true;
        }

        this.uiDialog.bind('dialogopen', function(event, ui) {
            if (self.options.isModal) {
                if ($(this).expose == null)
                    window.alert("Dialog box depends on the expose plugin to be modal. Please include the jquery tools Javascript include.");
                else {
                    $(this).expose({ opacity: 0.3
                            , color: '#CCCCCC'
                            , loadSpeed: 0
                            , closeSpeed: 0
                            , closeOnClick: false
                            , closeOnEsc: false
                            , api: true
                    }).load();
                }
            }
        });

        this.uiDialog.bind('dialogfocus', function(event, ui) {
            if (self.options.isModal) {
                $(this).css('z-index', '9999');
            }
        });

        this.uiDialog.bind('dialogclose', function(event, ui) {
            if (self.options.isModal) {
                if ($(this).expose != null) {
                    $(this).expose({ api: true }).close();
                }
            }
        });
    };

        $.ui.dialog.defaults.isModal = false;
})(jQuery);