开发者

jQuery-UI Dialog Memory Leaks

开发者 https://www.devze.com 2022-12-17 23:22 出处:网络
I\'m working with IE7 and some jQuery dialogs and I\'m running into about a 6meg leak per dialog opened. I\'m assuming it\'s to do with closures, but so far everything I\'ve done to remove them haven\

I'm working with IE7 and some jQuery dialogs and I'm running into about a 6meg leak per dialog opened. I'm assuming it's to do with closures, but so far everything I've done to remove them haven't helped. At this point I think I've taken care of all the closures except on for a callback function I pass in, but it's still leaking 6 megs even after the dialog is closed and removed. The relevant source code is:

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

One thing I did above that I'm not sure if it's needed was instead of defining the callback for the OK button when it's defined (and therefore having a closure since it's referencing the callback) to define it using a 开发者_JAVA百科.bind once the dialog is open. I was hoping that being able to pass the callback as part of the data to the click event might help remove the closure.

Any ideas what else I can change to get rid of this leak?


It actually ended up being caused by how the jQuery UI framework deals with graying out the background when displaying a modal. If I remove the modal = true and the overlay attributes the memory leak goes down to ~100k.

To get around this I had to make the dialog without the modal option, and then add a div myself to the page (fixed position top, left, bottom, right all 0 with a alternating gray pixel then transparent pixel background) and showing and hiding that with a zindex just under the dialog.

While it isn't ideal (the default modal overlay was nice and smooth looking) it's better than leaking that much memory per dialog I pop up.


Hope this helps, I created an extension for this issue where I use the jQuery tools (flowplayer) expose plugin when modal = true for the jQuery UI dialog.

I would include the folhttp://jsfiddle.net/yZ56q/lowing code in a separate .js file and make sure to include the jQuery tools expose plugin prior, from this site...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);
0

精彩评论

暂无评论...
验证码 换一张
取 消