zoukankan      html  css  js  c++  java
  • 如何避免JQuery Dialog的内存泄露(转)

    对于页面来说,JQuery中的Dialog从效果上来说还可以,而且使用简单,只要短短几行绑定的代码就可以实现弹出效果。
    代码
    $('#dialog').dialog({
    autoOpen:
    false,
    600,
    buttons: {
    "Ok": function() {
    $(
    this).dialog("close");
    },
    "Cancel": function() {
    $(
    this).dialog("close");
    }
    }
    });

    在一些JS交互性不多的一般页面来说,没有任何问题!但是对于交互性强的,需要动态加载与释放DOM的页面来说,它就是一个悲剧的东西!为什么这样说?大家看下下面的例子:

      一段简单的代码,一个DIV是通过动态加载到页面上,然后对该DIV用Dialog进行绑定,以达到弹出的目的!下面的test元素就是<div id="test"></div>。

    代码
    function TestAppend() {

    $(
    "#test").append('<div id="dialog"><div id="fileQueue"></div> <input type="file" name="uploadify" id="uploadify" />' +
    '<a href="javascript:upload();">上传</a>' +
    '<a href="javascript:$(#uploadify).uploadifyClearQueue()">取消上传</a><div>');

    $(
    '#dialog').dialog({
    autoOpen:
    false,
    600,
    buttons: {
    "Ok": function() {
    $(
    this).dialog("close");
    },
    "Cancel": function() {
    $(
    this).dialog("close");
    }
    }
    });

    return false;
    }

      接着,我需要删除该DOM元素,一般来说,正常的做法都是$("#test").empty();这行简单的代码就完成了!这样有效吗?!当执行完这样代码后,你再用$('#dialog')来获取dialog元素,郁闷的事情发生了,既然获取到了!为什么!不是已经empty了吗!

      下面我们来看下这一悲剧是如何造成的,

      我们把注意点放到$('#dialog').dialog上面,然后看看JQuery的实现代码是如何写的,当我们跟踪代码到dialog类中的_create方法的时候,问题的原因找到了,看下面这段代码:

    _create
    uiDialog = (self.uiDialog = $('<div></div>'))
    .appendTo(document.body)
    .hide()
    .addClass(uiDialogClasses
    + options.dialogClass)
    .css({
    zIndex: options.zIndex
    })
    // setting tabIndex makes the div focusable
    // setting outline to 0 prevents a border on focus in Mozilla
    .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
    if (options.closeOnEscape && event.keyCode &&
    event.keyCode === $.ui.keyCode.ESCAPE) {

    self.close(
    event);
    event.preventDefault();
    }
    })
    .attr({
    role:
    'dialog',
    'aria-labelledby': titleId
    })
    .mousedown(function(
    event) {
    self.moveToTop(
    false, event);
    }),

      它既然也动态创建一个div,而且把该div加到了Body上面,然后把dialog中的元素从<div id=test>中移除,加入到该新的div中.....

      这就是为什么我们$("#test").empty()后,却对内部的dialog没有起作用了!而且这有一个最不好的一个地方,也是最容易出现内存泄露的地方:它动态的在Body中创建了一个div,这样如果窗体不关闭的话,而你又在不察觉的情况下不断的使用上面的TestAppend方法来动态加载DOM,就会创建N个这样的div!

      其实这个问题郁闷的地方不是在如何解决,而且隐藏的很深,很难发现!那么发现之后解决起来就变的简单多了:

    if ($('#dialog')[0]) {
    $(
    '#dialog').parent().empty();
    $(
    '#dialog').parent().remove();
    }

    当前加上这段后代码后,再做$("#dialog")来测试下,期望的结果终于出现了!dialog元素消失了!

  • 相关阅读:
    Mbs Framework 简介
    回应老赵: 适合C# Actor的消息执行方式 中看也中用的解决方案
    Mini 容器学习笔记5—— 组件的获取
    JS控制文本框只能输入N个字符.
    【转】外挂编写原理
    【转】集合小节
    CSS样式的filter(滤镜效果)
    系统变量(%SystemRoot% ,%windir% ,%temp%,%system%)的表示方法
    客户端调用服务器控件
    Flash MX 认证考试(样题)
  • 原文地址:https://www.cnblogs.com/timy/p/2013357.html
Copyright © 2011-2022 走看看