如何解决jquery ui 1.7.2 的dialog的ie内存泄露

      1.7.2的dialog在ie每次打开对话框在ie都是使内存增长,得到ie浏览器的url切换了才会释放内存,如果把网站做成frame主体的,即进入到网站都是统一的url就是噩梦。

     先简单看下dialog的内存增长,打开development-bundle\demos\dialog\modal-form.html,点击”create new user”:

     刚打开时候时ie内存:

     image

     10重复点击”Create new user”——关闭:

     image

     修改ui.dialog.js:

显示行号 复制代码
  1. $.extend($.ui.dialog.overlay, {
        instances: [],
        oldInstances: [],    //修改一:添加oldInstances
        maxZ: 0,
        events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
            function(event) { return event + '.dialog-overlay'; }).join(' '),
        create: function(dialog) {
            if (this.instances.length === 0) {
                // prevent use of anchors and inputs
                // we use a setTimeout in case the overlay is created from an
                // event that we're going to be cancelling (see #2804)
                setTimeout(function() {
                    // handle $(el).dialog().dialog('close') (see #4065)
                    if ($.ui.dialog.overlay.instances.length) {
                        $(document).bind($.ui.dialog.overlay.events, function(event) {
                            var dialogZ = $(event.target).parents('.ui-dialog').css('zIndex') || 0;
                            return (dialogZ > $.ui.dialog.overlay.maxZ);
                        });
                    }
                }, 1);
                // allow closing by pressing the escape key
                $(document).bind('keydown.dialog-overlay', function(event) {
                    (dialog.options.closeOnEscape && event.keyCode
                            && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event));
                });
                // handle window resize
                $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
            }
            //修改二:替换var $el;
            //var $el = $('<div></div>').appendTo(document.body)
            //    .addClass('ui-widget-overlay').css({
            //        width: this.width(),
            //        height: this.height()
            //    });
            var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
                .appendTo(document.body)
                .css({
                    width: this.width(),
                    height: this.height()
                });    
            (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
  2.        this.instances.push($el);
            return $el;
        },
  3.    destroy: function($el) {
            //修改三:替换注释的代码:
            //this.instances.splice($.inArray(this.instances, $el), 1);
            this.oldInstances.push(this.instances.splice($.inArray($el, this.instances), 1)[0]);
            if (this.instances.length === 0) {
                $([document, window]).unbind('.dialog-overlay');
            }
            $el.remove();
            
            // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
            var maxZ = 0;
            $.each(this.instances, function() {
                maxZ = Math.max(maxZ, this.css('z-index'));
            });
            this.maxZ = maxZ;
        },
        height: function() {
            // handle IE 6
            if ($.browser.msie && $.browser.version < 7) {
                var scrollHeight = Math.max(
                    document.documentElement.scrollHeight,
                    document.body.scrollHeight
                );
                var offsetHeight = Math.max(
                    document.documentElement.offsetHeight,
                    document.body.offsetHeight
                );
                if (scrollHeight < offsetHeight) {
                    return $(window).height() + 'px';
                } else {
                    return scrollHeight + 'px';
                }
            // handle "good" browsers
            } else {
                return $(document).height() + 'px';
            }
        },
        width: function() {
            // handle IE 6
            if ($.browser.msie && $.browser.version < 7) {
                var scrollWidth = Math.max(
                    document.documentElement.scrollWidth,
                    document.body.scrollWidth
                );
                var offsetWidth = Math.max(
                    document.documentElement.offsetWidth,
                    document.body.offsetWidth
                );
  4.            if (scrollWidth < offsetWidth) {
                    return $(window).width() + 'px';
                } else {
                    return scrollWidth + 'px';
                }
            // handle "good" browsers
            } else {
                return $(document).width() + 'px';
            }
        },
        resize: function() {
            /* If the dialog is draggable and the user drags it past the
             * right edge of the window, the document becomes wider so we
             * need to stretch the overlay. If the user then drags the
             * dialog back to the left, the document will become narrower,
             * so we need to shrink the overlay to the appropriate size.
             * This is handled by shrinking the overlay before setting it
             * to the full document size.
             */
            var $overlays = $([]);
            $.each($.ui.dialog.overlay.instances, function() {
                $overlays = $overlays.add(this);
            });
  5.        $overlays.css({
                width: 0,
                height: 0
            }).css({
                width: $.ui.dialog.overlay.width(),
                height: $.ui.dialog.overlay.height()
            });
        }
    });

       修改后,重复点击后不会使内存增加很多,第一次点击的时候还是会使内存增加很多。

       跟踪代码,使内存增加就两个地方的appendTo(“body”):

       221行:(uiDialog.next().length && uiDialog.appendTo('body'));

       566行:var $el = $('<div></div>').appendTo(document.body)

       怎么解决这个问题还没什么好的方法,希望大家支持!

posted @ 2010-05-02 12:09  Asharp  阅读(4414)  评论(14编辑  收藏  举报