代码之家  ›  专栏  ›  技术社区  ›  Parrots

jquery用户界面对话框内存泄漏

  •  5
  • Parrots  · 技术社区  · 15 年前

    我正在处理IE7和一些jQuery对话框,我发现每个打开的对话框都有大约6兆的泄漏。我假设这与闭包有关,但到目前为止,我所做的所有移除操作都没有起到帮助。此时,我认为我已经处理了所有的闭包,除了我传入的回调函数,但是即使在关闭和删除对话框之后,它仍然会泄漏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);
    }
    

    上面我做的一件事是,我不确定是否需要它,而是在定义OK按钮时(因此在引用回调之后有一个闭包),用一个.bind来定义它,一旦对话框打开。我希望能够将回调作为数据的一部分传递给click事件可能有助于删除闭包。

    我还能换点什么来解决这个漏洞吗?

    2 回复  |  直到 15 年前
        1
  •  5
  •   Parrots    15 年前

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

    为了解决这个问题,我必须在不使用模式选项的情况下创建对话框,然后在页面中添加一个DIV(固定位置:顶部、左侧、底部、右侧,所有0都是灰色像素,然后是透明像素背景),并在对话框下方显示和隐藏Zindex。

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

        2
  •  1
  •   halfpastfour.am    13 年前

    希望这有帮助,我为这个问题创建了一个扩展,在这个扩展中,当jquery ui对话框的modal=true时,我使用jquery工具(flowplayer)公开插件。

    我将在一个单独的.js文件中包含以下代码http://jsfiddle.net/yz56q/lowing,并确保在此站点中包含jquery工具expose plugin prior… http://flowplayer.org/tools/download.html .

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